C, union, каламбур типизации
Подскажите, пожалуйста, что говорит Стандарт C о каламбуре типизации с использованием union? Разрешается ли писать в одно поле, а читать - из другого?
Ответы (1 шт):
Да, стандарт языка C (начиная с C991) позволяет писать в один член union, а читать — из другого:
6.5.2.3 Structure and union members
95) If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.
Однако, из цитаты очевидно, что в результате может получится trap representation. Так что единственный безопасный вариант каламбура типизации (англ. type punning) с использованием объединений — обращаться к значению члена объединения через тип unsigned char или unsigned char [], так как это единственный тип, который гарантированно не содержит trap representation:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
union {
int32_t i;
unsigned char u[4];
} t;
t.i = 13;
for (size_t i = 0; i < 4; ++i)
printf("%02x", t.u[i]);
}
- В стандарт C99 была добавлена специальная сноска под номером 78a. Цитата из Defect Report #257:
Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one. The rationale was that the behaviour would then depend on the representations of the values. Since this point is often misunderstood, it might well be worth making it clear in the Standard.