Acho que o padrão C11 cobre esse comportamento e diz que o resultado não é especificado , e não acho que o C18 tenha feito alterações relevantes nesta área.
A linguagem padrão não é fácil de analisar. A seção relevante do padrão é
§6.7.9 Inicialização . A sintaxe é documentada como:
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
Observe que um dos termos é expressão de atribuição e , como a[2] = 1
é indubitavelmente uma expressão de atribuição, é permitido dentro de inicializadores para matrizes com duração não estática:
§4 Todas as expressões em um inicializador para um objeto que tem duração de armazenamento estático ou thread devem ser expressões constantes ou literais de string.
Um dos parágrafos principais é:
§19 A inicialização deve ocorrer na ordem da lista de inicializadores, cada inicializador fornecido para um subobjeto particular substituindo qualquer inicializador listado anteriormente para o mesmo subobjeto; 151)
todos os subobjetos que não são inicializados explicitamente devem ser inicializados implicitamente da mesma forma que os objetos que têm duração de armazenamento estático.
151) Qualquer inicializador para o subobjeto que é sobrescrito e, portanto, não usado para inicializar aquele subobjeto pode não ser avaliado.
E outro parágrafo importante é:
§23 As avaliações das expressões da lista de inicialização são sequenciadas indeterminadamente umas em relação às outras e, portanto, a ordem em que os efeitos colaterais ocorrem não é especificada. 152)
152) Em particular, a ordem de avaliação não precisa ser igual à ordem de inicialização do subobjeto.
Tenho quase certeza de que o parágrafo §23 indica que a notação na questão:
int a[5] = { a[2] = 1 };
leva a um comportamento não especificado. A atribuição a a[2]
é um efeito colateral, e a ordem de avaliação das expressões são sequenciadas indeterminadamente uma em relação à outra. Consequentemente, não acho que haja uma maneira de apelar para o padrão e alegar que um compilador específico está lidando com isso correta ou incorretamente.
a[2]=1
avalia para1
.