Решение 2 является переносимым типом - соединение через профсоюзы всегда было законным в C99, и это было сделано явным образом в TC3, который добавил следующую сноску в раздел 6.5.2.3:
Если элемент, используемый для доступа к содержимому объекта объединения, не является
так же, как член последний раз использовался для хранения значения в объекте,
Соответствующая часть объекта представления значения
переосмысливается как представление объекта в новом типе, как описано
в 6.2.6 (этот процесс иногда называют «типом наказания»). Это может быть
представление ловушек.
Приложение J все еще перечисляет его как неопределенное поведение, которое является известным дефектом и было исправлено с помощью C11, который изменил
Значение члена объединения, кроме последнего, сохраненного в [, не указано ]
до
Значения байтов, которые соответствуют членам объединения, кроме последнего сохраненного
в [ не указаны ]
Это не так уж важно, так как приложение только информативное, а не нормативное.
Имейте в виду, что вы все равно можете получить неопределенное поведение, например
- путем создания представления ловушки
- путем нарушения правил псевдонимов в случае элементов с типом указателя (которые в любом случае не следует преобразовывать с помощью определения типов, так как не требуется единообразное представление указателя)
- если члены объединения имеют разные размеры - только байты члена, последнего использовавшегося в магазине, имеют указанное значение; в частности, сохранение значений в меньшем элементе также может сделать недействительными завершающие байты большего элемента
- если элемент содержит байты заполнения, которые всегда принимают неопределенные значения