注:ここではC++ 98準拠のコンパイラについて(おそらく)言います。これはC++ 11の問題ではありません。C++配列ゼロ初期化:これはバグですか?そうですか?
は、私たちは、コンパイラのいずれかで奇妙な行動を持っていると我々はこれがOKであればわからないか、これはコンパイラのバグの場合:BBBのような初期化され
// This struct has a default constructor
struct AAA
{
AAA() : value(0) {}
int value ;
} ;
// This struct has a member of type AAA and an array of int, both surrounded
// by ints
struct BBB
{
int m_a ;
AAA m_b ;
int m_c ;
int m_d[42] ;
} ;
:
BBB bbb = {0} ;
BBBのすべてのPODメンバー(m_d、intの配列を含む)がゼロ初期化され、BBBの非PODメンバーがすべて構築されると予想しました。
これは、Linux/GCC-3.4、Windows/VisualC++のAIXのネイティブコンパイラで動作しますが、Solaris/SunStudioでは非配列メンバーのみがゼロで初期化されます。
私たちは、次のを発見したC++ 98標準(ドラフト文書)、で、少し研究をした:
[12.6.1 - 2]
集約を(クラスまたは配列であるかどうかにかかわらず、クラス型のメンバを含み、中括弧で囲まれた初期化子リスト(8.5.1)で初期化されている場合、そのような各メンバは、対応する代入式によってコピー初期化される(8.5参照)。 initializer-listの初期化子が集約のメンバより少ない場合、明示的に初期化されていない各メンバは、デフォルトで初期化されます(8.5)。そして
:
[8.5から5]
にT型のオブジェクトのストレージをゼロに初期化手段:
- Tはスカラ型である場合(3.9 )、ストレージはT(ゼロ)の値に変換されます。
- Tが非共用クラス型である場合、各非静的データ・メンバーおよび各基本クラスのサブオブジェクトの記憶域はゼロで初期化されます。
- Tが共用体型の場合、その最初のデータメンバの記憶域89)はゼロで初期化されます。
- Tが配列型の場合、各要素の記憶域はゼロで初期化されます。
- Tが参照型の場合、初期化は実行されません。
そして:
するためのデフォルト初期化型Tの目的は、意味:
を - Tは、非PODクラス型(条項9)である場合、デフォルトのコンストラクタをTが呼び出されます(Tにアクセス可能なデフォルトコンストラクタがない場合、初期化は不正です)。
- Tが配列型の場合、各要素はデフォルトで初期化されます。
- この場合、オブジェクトのストレージはゼロで初期化されます。
私はそれを読む方法:SunStudioはゼロ初期化する必要がありintの配列(BBB :: M_D)を
奇妙なこと:私たちはAAAからデフォルトコンストラクタを削除する場合は、BBBですべてがありますゼロ初期化。
質問:POD以外の構造体を含む構造体のint配列のゼロ初期化に失敗した場合、SunStudioの動作は標準ですか?これはコンパイラのバグですか?
は私にはバグのように思えます。 'BBB bbb = {0,0,0、{0}};と書くとどうなるでしょうか? –
Sun CCではエラーです。標準の理解は正しいです。 –
@JamesKanze:私は本当にコメントをアップアップすることも、答えとして選択することもできません...完全な答えを作るのをためらっています...- – paercebal