If you try to read a union member other than the one that was last written, the results are not well-defined (except in some special cases where the union contains structures with compatible types). The standard says:
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.
So if you store into bar.a
and then try to read bar.b
, it reinterprets the contents of that memory as a float
. You don't get the same value because the reprentation of a floating point 10 is completely different from an integer 10.
Casting (int)bar.b
won't solve the problem because that will first interpret the contents as a float
and then convert that to an integer.
What you can do is use casting of a pointer to the member. However, I think this may violate the strict aliasing rule.
printf("%d %d\n", foo.a, *(int *)&foo.b);