Предположим, у меня есть союз:
union foo {
char a;
int i;
}
на платформе, где sizeof foo.i
> sizeof foo.a
,
Если я назначу foo.a
что происходит с остальной частью памяти, которая ранее была частью foo.i
?
Неизвестно, что происходит с памятью, в которую вы не написали. Компилятор может оставить его содержимое без изменений. Он может (например, по соображениям производительности) перезаписать предыдущее содержимое произвольными значениями.
Это неуказанное поведение для чтения из foo.i
после написания foo.a
именно по этой причине.
Интересно, что в стандарте C11 об этом ясно сказано в 6.2.6.1.7:
Когда значение сохраняется в члене объекта типа объединения, байты представления объекта, которые не соответствуют этому члену, но соответствуют другим членам, принимают неопределенные значения.
К сожалению, я не нашел ничего такого ясного в стандарте C ++ 14. Раздел 9.5 .:
В объединении не более одного члена нестатических данных может быть активным в любое время, то есть значение в
большинство из нестатических элементов данных могут быть сохранены в объединении в любое время. [Примечание: одна специальная гарантия
сделано для того, чтобы упростить использование объединений: если объединение стандартных макетов содержит несколько стандартных макетов
структуры, которые имеют общую начальную последовательность (9.2), и если объект этого типа объединения стандартного макета
содержит одну из структур стандартного макета, это разрешено проверять общую начальную последовательность любого из
члены структуры стандартного макета; см. 9.2. — конец примечания]
Эта гарантия странно конкретная, я не могу найти никаких гарантий относительно совместимые с макетом члены. Тем не менее, два типа разного размера не являются макет-совместимый, не может быть частью общие начальные последовательности. Я думаю, стандарт не разрешать проверять неактивных членов.
Это было бы дело к неопределенное поведение при доступе к значениям, хотя я бы поверил, что неопределенные значения иметь больше смысла.