Saya pikir standar C11 mencakup perilaku ini dan mengatakan bahwa hasilnya tidak ditentukan , dan menurut saya C18 tidak membuat perubahan apa pun yang relevan di area ini.
Bahasa standar tidak mudah diurai. Bagian yang relevan dari standar adalah
§6.7.9 Inisialisasi . Sintaksnya didokumentasikan sebagai:
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
Perhatikan bahwa salah satu termnya adalah assignment-expression , dan karena itu a[2] = 1
adalah ekspresi assignment, itu diperbolehkan di dalam penginisialisasi untuk array dengan durasi non-statis:
§4 Semua ekspresi dalam penginisialisasi untuk objek yang memiliki durasi penyimpanan statis atau utas harus ekspresi konstan atau literal string.
Salah satu paragraf kuncinya adalah:
§19 Inisialisasi akan terjadi dalam urutan daftar penginisialisasi, setiap penginisialisasi disediakan untuk subobjek tertentu yang menggantikan penginisialisasi yang terdaftar sebelumnya untuk subobjek yang sama; 151)
semua subobjek yang tidak diinisialisasi secara eksplisit harus diinisialisasi secara implisit sama dengan objek yang memiliki durasi penyimpanan statis.
151) Penginisialisasi apa pun untuk subobjek yang diganti sehingga tidak digunakan untuk menginisialisasi subobjek itu mungkin tidak dievaluasi sama sekali.
Dan paragraf kunci lainnya adalah:
§23 Evaluasi dari ekspresi daftar inisialisasi diurutkan secara tidak pasti terhadap satu sama lain dan dengan demikian urutan di mana efek samping yang terjadi tidak ditentukan. 152)
152) Secara khusus, urutan evaluasi tidak harus sama dengan urutan inisialisasi sub-objek.
Saya cukup yakin bahwa paragraf §23 menunjukkan bahwa notasi dalam pertanyaan:
int a[5] = { a[2] = 1 };
mengarah ke perilaku yang tidak ditentukan. Penugasan ke a[2]
adalah efek samping, dan urutan evaluasi ekspresi diurutkan secara tidak pasti terkait satu sama lain. Akibatnya, menurut saya tidak ada cara untuk menarik standar dan mengklaim bahwa kompilator tertentu menangani ini dengan benar atau salah.
a[2]=1
terevaluasi menjadi1
.