Reputation: 1
My code:
#include<stdio.h>
union U{
int x;
char y;
};
int main()
{
union U u1;
u1.x = 258;
u1.y = '0';
printf("%d%d",u1.x,u1.y);
return 0;
}
Strangely, the output is 30448
.
Can someone please explain how this happens?
Upvotes: 0
Views: 221
Reputation: 23802
You maybe missunderstanding the purpose of a union
. It is meant to store only one variable at a time, but this variable can have multiple types. The last variable stored will overwrite the previous.
In your case u1.y
(which is '0'
, it's relevant to remind that the 1 byte ASCII decimal representation for '0'
is 48
), is the last value stored, this corresponds to last 2 digits of your output as you print '0'
by its ASCII decimal representation.
As for the first part of the output, note that you overwrite the int
variable 258
, which is presumably 4 bytes (but for the sake of explanation I will assume it's 2 bytes) with the 1 byte wide char
variable 48
.
The binary value for 258
(assuming 2 bytes wide int
) is:
|0|0|0|0|0|0|0|1|0|0|0|0|0|0|1|0|
| 2nd byte | 1st byte |
The binary value for 48
(1 byte wide char
variable) is:
| | | | | | | | |0|0|1|1|0|0|0|0|
| 1st byte |
When you overwrite the two byte union variable with a one byte variable only the 8 least significant bits(least significant byte) will be overwritten, so you'll end up with:
|0|0|0|0|0|0|0|1|x|x|x|x|x|x|x|x|
| | | | | | | | |0|0|1|1|0|0|0|0|
|0|0|0|0|0|0|0|1|0|0|1|1|0|0|0|0|
And this is the binary representation of 304
.
So yor code first prints the 2 bytes wide (for the sake of the examle) int
304
and next the 1 byte wide int
48
(the ASCII int
representation of '0'
), hence the output 30448
.
Note that this behavior is not undefined.
§ 6.5.2.3
97) 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.
§ 6.2.6.2
6 - When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.51) The value of a structure or union object is never a trap representation, even though the value of a member of the structure or union object may be a trap representation.
7 - When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.
For confirmation you can use:
printf("%p %p\n", (void*)&u1.x, (void*)&u1.y);
This will print the memory address of both u1.x
and u1.y
and you will not be shocked to find that they are the same.
Upvotes: 3
Reputation: 108938
You cannot read a member of a union other than the one last written into
#include<stdio.h>
union U{
int x;
char y;
};
int main()
{
union U u1;
u1.x = 258; // write into member x: OK
u1.y = '0'; // write into member y: OK
printf("%d%d",u1.x,u1.y); // read both member x and y: WRONG
// can only read member y
return 0;
}
Upvotes: -1