4
struct
{
    int a,b;
} s = {5, s.a+1};

規格によれば、上記の例で「sa」と読み、s を a=5 および b=6 に初期化しても安全ですか? もしそうなら、ほとんどのコンパイラはこの規則に従いますか?

(上記は VC10 でコンパイルされます。)

4

1 に答える 1

3

はい、集合メンバーの初期化が順序付けられているためです。

[dcl.init.aggr] /2 には:

8.5.4 で指定されているように、集合体が初期化子リストによって初期化されると、初期化子リストの要素は、添え字またはメンバーの昇順で、集合体のメンバーの初期化子として取得されます。各メンバーは、対応するinitializer-clauseからコピー初期化されます。

[dcl.init.list] /4 には:

braced-init-listinitializer-list内で、pack展開 (14.5.3) の結果を含むinitializer-clausesは、出現順に評価されます。つまり、指定されたinitializer-clauseに関連付けられたすべての値の計算と副作用は、 initializer-listのコンマ区切りのリストでそれに続くすべてのinitializer-clauseに関連付けられたすべての値の計算と副作用の前に並べられます。

集約メンバーのコピー初期化は確かに副作用 ( [ intro.execution] /12) であり、対応するinitializer-clause「関連付ける」必要があります表現ではありません)。

私が試した最新のコンパイラ (MSVC、Clang、g++) はすべて、これを正しくコンパイルします。一部の古いコンパイラが間違っている可能性があります (g++ の古いバージョンは、集計初期化子の順序付けが間違っていることが知られていました)。

于 2015-02-25T14:48:48.070 に答える