C11標準はこの動作をカバーし、結果は不特定であると述べています。C18がこの領域に関連する変更を行ったとは思いません。
標準言語は解析が容易ではありません。標準の関連セクションは
§6.7.9初期化です。構文は次のように文書化されています。
initializer:
assignment-expression
{ initializer-list }
{ initializer-list , }
initializer-list:
designation
opt
initializer
initializer-list , designation
opt
initializer
designation:
designator-list =
designator-list:
designator
designator-list designator
designator:
[ constant-expression ]
. identifier
用語の1つは割り当て式であることに注意してください。これa[2] = 1
は間違いなく割り当て式であるため、非静的期間の配列の初期化子内で許可されます。
§4静的またはスレッドの保存期間を持つオブジェクトの初期化子のすべての式は、定数式または文字列リテラルでなければなりません。
重要な段落の1つは次のとおりです。
§19初期化はイニシャライザリストの順序で行われます。各イニシャライザは特定のサブオブジェクトに提供され、同じサブオブジェクトの以前にリストされた初期化子をオーバーライドします。151)
明示的に初期化されていないすべてのサブオブジェクトは、静的ストレージ期間を持つオブジェクトと同じように暗黙的に初期化されます。
151)オーバーライドされ、そのサブオブジェクトの初期化に使用されないサブオブジェクトの初期化子は、まったく評価されない可能性があります。
もう1つの重要な段落は次のとおりです。
§23初期化リスト式の評価は、相互に不定に順序付けられているため、副作用が発生する順序は規定されていません。152)
152)特に、評価順序はサブオブジェクトの初期化の順序と同じである必要はありません。
私は、§23項が問題の表記法を示していることをかなり確信しています:
int a[5] = { a[2] = 1 };
不特定の行動につながります。への代入a[2]
は副作用であり、式の評価順序は相互に不確定に順序付けられます。したがって、標準にアピールし、特定のコンパイラがこれを正しくまたは誤って処理していると主張する方法はないと思います。
a[2]=1
評価され1
ます。