Myślę, że standard C11 obejmuje to zachowanie i mówi, że wynik jest nieokreślony i nie sądzę, aby C18 wprowadził jakiekolwiek istotne zmiany w tym obszarze.
Język standardowy nie jest łatwy do przeanalizowania. Odpowiednią sekcją normy jest
§6.7.9 Inicjalizacja . Składnia jest udokumentowana jako:
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
Zwróć uwagę, że jednym z terminów jest wyrażenie przypisania , a ponieważ a[2] = 1
jest to niewątpliwie wyrażenie przypisania, jest dozwolone wewnątrz inicjatorów dla tablic o niestatycznym czasie trwania:
§4 Wszystkie wyrażenia w inicjatorze dla obiektu, który ma statyczny lub wątkowy czas trwania, powinny być wyrażeniami stałymi lub literałami łańcuchowymi.
Jednym z kluczowych akapitów jest:
§19 Inicjalizacja powinna odbywać się w kolejności listy inicjalizatorów, przy czym każdy inicjalizator przewidziany dla określonego podobiektu przesłania wszelkie poprzednio wymienione inicjatory dla tego samego podobiektu; 151)
wszystkie podobiekty, które nie zostały zainicjowane jawnie, zostaną zainicjowane niejawnie tak samo, jak obiekty o statycznym czasie trwania.
151) Każdy inicjator dla podobiektu, który jest przesłonięty i nie jest używany do zainicjowania tego podobiektu, może w ogóle nie zostać oceniony.
Kolejny kluczowy akapit to:
§23 Oceny wyrażeń listy inicjalizacyjnej są nieokreślone względem siebie, a zatem kolejność, w jakiej występują jakiekolwiek skutki uboczne, jest nieokreślona. 152)
152) W szczególności kolejność oceny nie musi być taka sama jak kolejność inicjalizacji podobiektu.
Jestem prawie pewien, że paragraf 23 wskazuje, że zapis w pytaniu:
int a[5] = { a[2] = 1 };
prowadzi do nieokreślonego zachowania. Przypisanie do a[2]
jest efektem ubocznym, a kolejność oceny wyrażeń jest nieokreślona względem siebie. W związku z tym nie sądzę, aby można było odwołać się do standardu i twierdzić, że konkretny kompilator obsługuje to poprawnie lub nieprawidłowo.
a[2]=1
zwraca1
.