web-dev-qa-db-ja.com

C ++構造体を `= {0}`に初期化しないと、そのすべてのメンバーが0に設定されないのはなぜですか?

大量のテストと書き込みを行った後 この答え (注:それに対する私の反対票は、それを完全に書き換える前でした)、= {0}がすべてのメンバーを設定しない理由がわかりません構造体のゼロに!

これを行う場合:

struct data_t
{
    int num1 = 100;
    int num2 = -100;
    int num3;
    int num4 = 150;
};

data_t d3 = {0};
printf("d3.num1 = %i\nd3.num2 = %i\nd3.num3 = %i\nd3.num4 = %i\n\n",
       d3.num1, d3.num2, d3.num3, d3.num4);

...出力は次のとおりです。

d3.num1 = 0
d3.num2 = -100
d3.num3 = 0
d3.num4 = 150

...私は期待されますが出力はこれです:

d3.num1 = 0
d3.num2 = 0
d3.num3 = 0
d3.num4 = 0

...つまり、FIRSTメンバーのみがゼロに設定され、残りはすべてデフォルトに設定されました。

これらの3つの方法のいずれかで構造体を初期化するとゼロで初期化されるという印象を常に受け​​ていましたが、明らかに私は間違っています!

  1. data_t d{}
  2. data_t d = {}
  3. data_t d = {0}

この答え からの私の重要なポイントは次のとおりです:

ここで重要なのは、data_t d{}data_t d = {}、およびdata_t d = {0}のどれも実際には、構造体のすべてのメンバーをゼロに設定していないことです。

  1. data_t d{}は、すべての値を構造体で定義されているデフォルトに設定します。
  2. data_t d = {}もすべての値をデフォルトに設定します。
  3. また、data_t d = {0}は、FIRST値のみをゼロに設定し、他のすべての値をデフォルトに設定します。

それでは、なぜC++構造体を= {0}に初期化して、そのすべてのメンバーを0に設定しないのですか?

上記の私の重要な要点は、私が長年使用してきたこのかなり公式に見えるドキュメントと実際には矛盾していることに注意してください( https://en.cppreference.com/w/cpp/language/zero_initialization )、これは、T t = {} ;T {} ;がどちらもゼロの初期化子であることを示しています。実際、私のテストと上記のテイクアウトによれば、実際はそうではありません。

参照:

  1. C++で構造体を0に初期化する方法
  2. 更新:私もこの参照を指摘されました: オブジェクトを初期化するときの{0}の意味?
4
Gabriel Staples

短い答え:クラス内初期化子があるからです。

より長い答え:C++ 14以降用にコンパイルしているので、クラス内初期化子を持ち、 集約初期化 を使用しています。リファレンスは説明を提供します:

初期化句の数がメンバーの数より少ない場合、または初期化リストが完全に空の場合、残りのメンバーは、クラス定義で指定されている場合はデフォルトのメンバー初期化子によって初期化され、そうでない場合は(C++ 14以降)空のリストによって初期化されます。 、通常のリスト初期化規則に従って(デフォルトのコンストラクターを使用して非クラス型および非集合クラスの値の初期化を実行し、集約の集約初期化を実行します)。

allデータメンバーをゼロ初期化するには、クラス内初期化子なしでデータメンバー宣言のみを提供し、次に_= {0}_または_={}_構文:

_struct data_t
{
    int num1;
    int num2;
    int num3;
    int num4;
};

int main()
{
    data_t d3 = { 0 };
    printf("d3.num1 = %i\nd3.num2 = %i\nd3.num3 = %i\nd3.num4 = %i\n\n",
        d3.num1, d3.num2, d3.num3, d3.num4);
}
_

これで、すべてのデータメンバーが_0_に初期化されます。

2
Ron