В итоге: {1, 2, .things = NULL}
попытки инициализировать элемент массива test
, который называется things
, но массив не имеет элемент с именем things
, так что это является недопустимым. Напротив, {1, 2, {.things = NULL}}
пытается инициализировать элемент второго элемента массива с именем things
, а второй элемент массива - это объединение, которое имеет член с именем things
, поэтому это действительно.
Per C 2011 (N1570) 6.7.9 17:
Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator.
Существует еще в последующих пунктах о том, как текущий объект обрабатывается, но это достаточно. В списке инициализаторов, заключенном в скобки, 1
- простой инициализатор; у него нет никаких обозначений. Таким образом, он инициализирует подобъект массива, который является элементом массива. Аналогично 2
инициализирует другой элемент. Затем мы имеем .things = NULL
. У этого есть указатель, .things
.
В соответствии с цитируемым абзацем этот указатель .things
вызывает инициализацию подобъекта, описанного .things
. Но в массиве нет ничего, что обозначено .things
. Это только массив с индексированными элементами, обозначенный [index]
. У него нет членов, назначенных .thigns
. Таким образом, есть ошибка.
Во втором списке, где используются дополнительные распорки, пункт 20 применяется:
If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching right brace initialize the elements or members of the subaggregate or the contained union.…
В этом случае {.things = NULL}
начинается с левой фигурной скобкой. Это говорит о том, что инициализаторы, содержащиеся в фигурных скобках, инициализируют текущий объект большего списка. Поэтому они инициализируют следующий элемент массива (элемент с индексом 2). Любой элемент массива представляет собой объединение с членом с именем things
, поэтому .things
обозначает в нем подобъект, и этот синтаксис является приемлемым.
Возможный дубликат: [инициализировать массив объединения при объявлении] (http://stackoverflow.com/questions/11558390/initialize-a-union-array-at-declaration). См. Первый [ответ] (http://stackoverflow.com/a/11558466/519383). –
Не думаю, что я использую C99 уже, мне интересно, зачем нужны внутренние фигурные скобки ... – drigoSkalWalker
В этом вопросе нет сложных литералов. –