Reputation: 13702
I have this code:
typedef union MyUnion {
int ival;
float fval;
} MyUnion;
MyUnion myUnion;
myUnion.fval = 3.0f;
someFuncCall(myUnion.ival);
What exactly am I doing when I ask for the ival? It is my guess that I am asking for the float to be thought of (encoded as?) an int. I also assume that it has to do with sharing the same space in memory? However, I am definitely uncertain. This is a trick I had to use when sending float data to an FPGA in the Vivado Suite. All data is expected to enter as ints. I'd really appreciate any thorough clarification for what is going on or just pointers to resources. Thanks!
Upvotes: 0
Views: 141
Reputation: 133609
According to the standard IEC9899/2011 §6.5.2.3, note 95 you have that:
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 indeed what you are trying to do works but it could lead to problems (eg. different sizes for the members or different memory alignment).
Upvotes: 2
Reputation: 1528
You're taking raw bits of a float
and interpet them as an int
. A union works by allocating memory for the biggest (in terms of sizeof
) field and overwriting that part of memory every time you assign a value to a union's field.
In your example sizeof(int) == sizeof(float)
probably holds (both are 32 bits) and instead of using an union, you could write:
float f = 3.0f;
someFuncCall(*(int*)&f);
Generally, however, you do not know how the union's fields are aligned in memory. Take the following union:
union SomeUnion {
char c;
int i;
}
SomeUnion::c and SomeUnion::i might be aligned on either HO
or LO
boundary and it is implementation dependant.
Upvotes: 1