2016-12-06 6 views
0

数年前、{}と{0}を使ってPODの初期化にC++の微妙な違いがありました。C++での{}と{0}の間の初期化の差

D3D11_TEXTURE2D_DESC dsd = {}; 
D3D11_TEXTURE2D_DESC dsd2 = { 0 }: 

私は{0}確かにCから継承されたものです、それは{}の両方が、おそらく同じにmemsetにコンパイル時に翻訳され、C++ 11で導入された何か()の呼び出しであることを知っていますが:

memset(&dsd, 0, sizeof(dsd)); 

しかし、2つのブレース初期化スタイルのうちの1つは、メモリの初期化が整列されていないものでしたが、どんなスタイルが優れているのか気になるのは誰ですか?

+1

さらに進む前に、ゴッドボルトに飛び乗って、これらのことが実際に何をしているのか自分自身で見てください。 D3D11_TEXTURE2D_DESCの代わりにテスト構造を自由に設定してください。 –

+0

'{}'の使用は少なくともC++ 03以来のことです。 – juanchopanza

+1

このページを見てくださいhttp://en.cppreference.com/w/cpp/language/list_initialization –

答えて

6

参照する構文はaggregate initializationです。

イニシャライザ句の数がメンバーまたは初期化子リストの数が完全に空であるよりも小さい場合PODの値の初期化がゼロと同様であるので、残りのメンバーは、値に初期化

あります初期化では、表示する2つの構文に違いはありません。

これは、C++ 11より前のケースでもありました。空の初期化子リストは、導入されたものではありませんでした。 C++ 11以来、シンタックスはPOD以外のものにも許されています。集約初期化は、この新しいリスト初期化の特殊なケースになりました。

-6

どちらのバージョンも「C++ 11で導入されたもの」です。ブレースの初期化は、単にコンストラクタを呼び出す方法です。例えば。 D3D11_TEXTURE2D_DESC dsd = {};はデフォルトのコンストラクタを呼び出し、D3D11_TEXTURE2D_DESC dsd2 = { 0 };はこれを呼び出します。これはconst intを唯一のパラメータとして呼び出すことができます。コンストラクタのいずれかがそうしない限り、どちらもmemset(&dsd, 0, sizeof(dsd));に似たものに変換されません。

暗黙的に宣言されているデフォルトのコンストラクタがある場合は、そのすべての要素のデフォルトコンストラクタが呼び出されます。struct組み込み型のデフォルトコンストラクタは何もしないので、メモリはゼロに設定されません。

structについては、コンストラクタが定義されておらず、パブリックメンバーのみ、さらにいくつかの制限があり、C structに沸騰すると、aggregate initializationとなります。それは基本的にはCから来ると期待しています。とにかく、D3D11_TEXTURE2D_DESC dsd2 = { 0 };memset(&dsd, 0, sizeof(dsd));と等価ではありません。なぜなら、コンパイラは何らかの理由でクラスにパディングを追加する可能性があります。もちろん、フィールドの型は、 。

[OK]をクリックします。これでどちらが優れているかはもちろん、達成しようとするものによって異なります。 C structを処理している場合は、初期化されていない値を取得しないため、2番目の値を使用することをお勧めします。しかし、memset()などの前提を忘れてください。代わりにコンストラクタを見てください。

+0

いいえ、どちらのバージョンも少なくともC++ 03以来利用可能でした。 OPはPODについて話しているので、セマンティクスでさえもC++ 11より前です。 – juanchopanza

+1

さて、C++ 11は新しいもの(初期化子リストを受け入れるコールコンストラクタ)を変更しましたが、その構文はC++ 11より前に動作していました。 –

+0

オペレータがOPを指定したので、コンストラクタはPODの初期化です。 – aschepler