The standard says that
6.2.5 Types:
A union type describes an overlapping nonempty set of member objects, each of which has an optionally specified name and possibly distinct type.
The compiler allocates only enough space for the largest of the members, which overlay each other within this space. In your case, memory is allocated for int
data type (assuming 4-bytes). The line
union a z = {512};
will initialize the first member of union z
, i.e. x
becomes 512
. In binary it is represented as 0000 0000 0000 0000 0000 0010 0000 0000
on a 32 machine.
Memory representation for this would depend on the machine architecture. On a 32-bit machine it either will be like (store the least significant byte in the smallest address-- Little Endian)
Address Value
0x1000 0000 0000
0x1001 0000 0010
0x1002 0000 0000
0x1003 0000 0000
or like (store the most significant byte in the smallest address -- Big Endian)
Address Value
0x1000 0000 0000
0x1001 0000 0000
0x1002 0000 0010
0x1003 0000 0000
z.y[0]
will access the content at addrees 0x1000
and z.y[1]
will access the content at address 0x1001
and those content will depend on the above representation.
It seems that your machine supports Little Endian representation and therefore z.y[0] = 0
and z.y[1] = 2
and output would be 0 2
.
But, you should note that footnote 95 of section 6.5.2.3 states 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.