I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
§6.7.9 Initialization.
The syntax is documented as:
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
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
§4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
§19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
§23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph §23 indicates that the notation in the
question:
int a[5] = { a[2] = 1 };
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.