Consider this code:
int x[1] = {[0] = 1, [0] = 2};
Which value x[0]
has?
Experimentally the last designator takes effect (i.e. x[0]
has value 2
). However, does the C standard prescribe that "the last designator takes effect" (or similar wording)?
If there is no need to prescribe it, then how can it be deduced that "the last designator takes effect"?
(I've briefly looked into C11 6.7.9 Initialization and into C2y 6.7.11 Initialization and have found nothing which addresses this case. Maybe I've overlooked something.)
C 2024 6.7.11 says:
… The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject;…
Therefore, int x[1] = {[0] = 1, [0] = 2};
initializes x[0]
to 2.
In C 2011 (draft N1570) and C 2018, this is 6.7.9 paragraph 19.
Also, there is a footnote that says:
Any initializer for the subobject which is overridden and so not used to initialize that subobject can potentially not be evaluated at all.
Thus, if the code were int x[1] = {[0] = foo(), [0] = 2};
, a compiler might choose not to call foo
. Indeed, Clang, GCC, and MSVC elide the evaluation.