В стандарте C11 существует следующее определение общей исходной последовательности, разделяемой структурами, вложенными в один союз:
6.5.2.3/6
Для упрощения использования профсоюзов существует одна специальная гарантия: если объединение содержит несколько структур, которые имеют общую начальную последовательность (см. Ниже), и если объект объединения в настоящее время содержит одну из этих структур, разрешается проверять общие начальная часть любого из них в любом месте, где видна декларация завершенного типа объединения. Две структуры имеют общую начальную последовательность, если соответствующие члены имеют совместимые типы (и для бит-полей, одинаковые ширины) для последовательности из одного или нескольких начальных членов.
ПРИМЕР 3 Ниже приведен допустимый fragment:
- Как отличить C struct только от другого типа структуры, если их размер памяти равен?
- Структуры и союзы в C, определяющие размер и доступ к членам
- Союз структур с общим первым членом
- Заполнение в союзе присутствует или нет
- Каковы преимущества неназванных структур / союзов в C?
union { struct { int alltypes; } n; struct { int type; int intnode; } ni; struct { int type; double doublenode; } nf; } u; u.nf.type = 1; u.nf.doublenode = 3.14; /* ... */ if (unalltypes == 1) if (sin(u.nf.doublenode) == 0.0) /* ... */
Согласно моему пониманию этой статьи, приведенный выше код недействителен.
В внешнем операторе if
мы указываем, что n::alltypes
данных n::alltypes
активен (одновременно с ni::type
и nf::type
как стандартные состояния), но во внутреннем, if
мы используем nf::doublenode
который не является частью общая начальная последовательность.
Может кто-нибудь прояснить эту проблему?
разрешено проверять общую начальную часть [нескольких структур, которые имеют общую начальную последовательность]
Используя предоставленный пример, эта часть спецификации говорит о том, что, поскольку каждый возможный тип члена union
имеет int
как начальное поле, вы можете получить доступ к этому обычному начальному полю, используя любой из типов членов, даже после того, как переменная была инициализирована / используется как один из конкретных типов членов.
Это как раз то, что делает этот пример: он обращается к начальному int
как члену типов alltypes
из n
, после инициализации следующих полей как nf
, а затем переходит к получению doublenode
поля nf
, используя одну и ту же переменную.
Использование union
как одного из возможных типов не приводит к тому, что он работает в какой-то структуре: так работают профсоюзы.
Обратите внимание, что эта гарантия существует в течение некоторого времени: по существу один и тот же текст находится в спецификации ANSI , раздел: 3.3.2.3. Структура и члены объединения .