14

私は次のコードを持っていました:

#include <iostream>

struct T
{
   int a, b, c;
};

int main()
{
   T t = {0};
   std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}

出力

0,0,0

このコードが重要な本番環境で問題なく実行され、重要な機能を果たした後、プロジェクトの要件が変更され、出力をである必要がありました1,1,1

だから、私はに変更{0}しました{1}

#include <iostream>

struct T
{
   int a, b, c;
};

int main()
{
   T t = {1};
   std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}

出力

1,0,0

1,1,1代わりに期待していました。

なぜ私structのメンバー全員が適切に初期化されていないのですか?

4

1 に答える 1

32

を書くとき、それは最初のメンバー= {0}を明示的に初期化するだけです; 残りは標準に従って暗黙的にゼロで初期化されるため、一見すると、作成したものですべてのメンバーを明示的に初期化したように見えますが、そうではありませんでした。0

あなたが書いた場所0は最初のメンバーにのみ影響します。したがって、ある日、1すべてのメンバーが変更されると考えるように変更すると、ここのようなバグが発生します。誤解を招く/危険な/愚かな/壊れやすいコードです。

そのため、説明コメントを添付し= {0}ないと、私のチームのコードレビューに合格しません。あなたはもともと書いているべきでした:

T t = {};

そして今、新しい要件に従って問題を解決するには、次のように書く必要があります。

T t = {1,1,1};

structまたは、 POD性を失う可能性を気にしない場合はT、コンストラクターを提供します。


正式な文言

[C++11: 8.5.1/2]:8.5.4で指定されているように、アグリゲートがイニシャライザリストによって初期化されると、イニシャライザリストの要素は、添え字またはメンバーの順序の昇順で、アグリゲートのメンバーのイニシャライザとして使用されます。各メンバーは、対応するinitializer-clauseからコピー初期化されます。initializer-clauseが式であり、式を変換するためにナローイング変換(8.5.4)が必要な場合、プログラムの形式が正しくありません。[..]

[C++11: 8.5.1/6]:イニシャライザ句の数が初期化するメンバーまたは要素の数を超える場合、イニシャライザリストの形式が正しくありません。

[C++11: 8.5.1/7]: リスト内の初期化句が集約内のメンバーよりも少ない場合、明示的に初期化されていない各メンバーは、空の初期化子リスト(8.5.4)から初期化されます。

于 2013-02-10T12:37:36.607 に答える