Стандарт (C11) гласит в §6.7.2.1 Спецификаторы структуры и объединения *3 - ограничение:
¶3 Структура или объединение не должны содержать члена с неполным или функциональным типом (следовательно, структура не должна содержать своего экземпляра, но может содержать указатель на свой экземпляр), за исключением того, что последний член структура с более чем одним именованным членом может иметь неполный тип массива; такая структура (и любое объединение, содержащее, возможно, рекурсивно член, являющийся такой структурой) не должно быть членом структуры или элементом массива.
Обратите внимание, что только структуры могут (напрямую) содержать член гибкого массива - объединения не могут.
Первый случай законен. Второе нет.
(Это §6.7.2.1 ¶18 , который определяет термин элемент гибкого массива .)
Между прочим, в первой версии вопроса оператор printf()
в первом примере обращался к элементу массива, который не был выделен - дефект, который с тех пор был исправлен в ревизии 2 Запись union test test;
дает вам массив размером 0. Вы должны использовать динамическое выделение памяти (или какой-либо другой механизм ), чтобы выделить объединение или структуру с достаточным пространством для не пустой FAM. Аналогичные комментарии применимы и ко второму примеру.
Некоторое имя говорится в комментарии
Но поскольку в первом случае структура является анонимной, поэтому члены структуры должны рассматриваться как члены содержащего объединения, в котором объединение содержит элемент гибкого массива. Как я цитировал Члены анонимной структуры или объединения считаются членами содержащей структуры или объединения.
Обратите внимание, что анонимная структура не теряет свою форму только потому, что она встроена в объединение. Одно из отличий состоит в том, что смещение b
в union test
не может быть 0, что полностью отличается от нормальных членов объединения. Обычно все члены объединения начинаются со смещения 0. В основном, это говорит о том, что с учетом переменной union test u;
вы можете ссылаться на u.a
и u.b
. В прошлом вам приходилось указывать имя для структуры: union test { struct { int a; int b[]; } s; };
и использовать u.s.a
или u.s.b
для доступа к элементам структуры в объединении. Это не влияет на то, где допускается использование гибкого элемента массива; только обозначение, используемое для доступа к нему.