5

次のプログラムでは:

#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]) に標準で定義されているかどうか。

定義済みまたは未定義として明示的に記載されていますか? それとも、明示的に定義されていないという理由だけで未定義になりますか?

または、評価順序以外の他の理由により、構造体に定義済みまたは未定義の動作がありますか?

4

1 に答える 1