저는 C11 표준이이 동작을 다루고 결과가 명시되지 않았다고 말합니다. 않았다고 . 그리고 C18이이 영역에서 관련 변경 사항을 적용하지 않았다고 생각합니다.
표준 언어는 파싱하기가 쉽지 않습니다. 표준의 관련 섹션은
§6.7.9 초기화 입니다. 구문은 다음과 같이 문서화됩니다.
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
용어 중 하나는 assignment-expression 이며 a[2] = 1
, 확실히 할당 표현식이므로 비 정적 기간을 가진 배열의 이니셜 라이저 내에서 허용됩니다.
§4 정적 또는 스레드 저장 기간이있는 개체에 대한 이니셜 라이저의 모든 식은 상수 식 또는 문자열 리터럴이어야합니다.
주요 단락 중 하나는 다음과 같습니다.
§19 초기화는 이니셜 라이저 목록 순서로 발생해야하며, 각 이니셜 라이저는 동일한 하위 개체에 대해 이전에 나열된 이니셜 라이저를 재정의하는 특정 하위 개체에 제공됩니다. 151)
명시 적으로 초기화되지 않은 모든 하위 객체는 정적 저장 기간이있는 객체와 동일하게 암시 적으로 초기화됩니다.
151) 재정의되어 해당 하위 개체를 초기화하는 데 사용되지 않는 하위 개체에 대한 이니셜 라이저는 전혀 평가되지 않을 수 있습니다.
또 다른 핵심 단락은 다음과 같습니다.
§23 초기화 목록 식의 평가는 서로에 대해 불확실하게 순서가 지정되므로 부작용이 발생하는 순서는 지정되지 않습니다. 152)
152) 특히, 평가 순서는 하위 객체 초기화 순서와 같을 필요는 없습니다.
나는 단락 §23이 질문의 표기법을 나타냅니다.
int a[5] = { a[2] = 1 };
지정되지 않은 동작으로 이어집니다. 할당 a[2]
은 부작용이며 표현식의 평가 순서는 서로에 대해 불확실하게 순서가 지정됩니다. 결과적으로 나는 표준에 호소 할 방법이 없다고 생각하고 특정 컴파일러가 이것을 올바르게 또는 잘못 처리하고 있다고 주장합니다.
a[2]=1
평가됩니다1
.