I read that this code it is undefined according to the c standard but I cant find why. It is compiles without errors in gcc 8.1.0 and clang-6.0 and prints 1.
the code is as follows:
#include <stdio.h>
int main()
{
union {
int i;
short s;
} u;
u.i = 42;
u.s = 1;
printf("%d\n", u.i);
return 0;
}
From the C11 specification, §6.5.2.3 note 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.
This says that what you're doing is allowed, but also implies that the value you read may not be what you expect (for example by writing to an int
member and reading from a float
member).
There's also the caveat about trap representation values in which case the behavior will be undefined. For two's complement systems (which is the vast majority of all computers the last couple of decades) this isn't an issue with integer values though.
In your case the result will depends very much on the platforms endianness. Either you will get the value you write (1
) or you will get 0
.
union { int i; short s; } u; u.i = 42; u.s = 1;`
What happens when you assign a value to u.i
that's larger than a short can hold? For example, try this:
u.i = 40000;
u.s = 1;
Should the compiler clear out the entire space reserved for u
before assigning the short, or should it just write the bytes needed to store the new value? Since it's your responsibility to keep track of how to interpret the value stored in u
, storing one type and then reading a different type of a different size seems like a poor plan.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With