次のプログラムでは:
#include <iostream>
struct I {
int i;
I(){i=2;}
I(int _i){i=_i;}
};
int a[3] = {a[2] = 1};
int aa[3][3] = {aa[2][2] = 1};
I A[3] = {A[2].i = 1};
I AA[3][3] = {AA[2][2].i = 1};
int main(int argc, char **argv) {
for (int b : a) std::cout << b << ' ';
std::cout << '\n';
for (auto &bb : aa) for (auto &b : bb) std::cout << b << ' ';
std::cout << '\n';
for (auto &B : A) std::cout << B.i << ' ';
std::cout << '\n';
for (auto &BB : AA) for (auto &B : BB) std::cout << B.i << ' ';
std::cout << '\n';
return 0;
}
出力は
1 0 0
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
http://ideone.com/1ueWdKから clang3.7で
しかし、結果は次のとおりです。
0 0 1
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
http://rextester.com/l/cpp_online_compiler_clangでは、clang 3.7 も使用できます。
私自身のubuntuでは、gcc 6.2はconstructで内部コンパイラエラーを引き起こしますint aa[3][3] = {aa[2][2] = 1}
。
これは未定義の動作であると想定していますが、標準で決定的なステートメントを見つけることができません。
質問は:
副作用の評価順序は、イニシャライザ リストの代入 (例a[2] = 1
) および配列の実際の要素の初期化 (例a[2]
) に標準で定義されているかどうか。
定義済みまたは未定義として明示的に記載されていますか? それとも、明示的に定義されていないという理由だけで未定義になりますか?
または、評価順序以外の他の理由により、構造体に定義済みまたは未定義の動作がありますか?