This is undefined behaviour. u.i
and u.ch
are located at the same memory address. So, the result of writing into one and reading from the other depends on the compiler, platform, architecture, and sometimes even compiler’s optimization level. Therefore the output for u.i
may not always be 515
.
Example
For example gcc
on my machine produces two different answers for -O0
and -O2
.
-
Because my machine has 32-bit little-endian architecture, with
-O0
I end up with two least significant bytes initialized to 2 and 3, two most significant bytes are uninitialized. So the union’s memory looks like this:{3, 2, garbage, garbage}
Hence I get the output similar to
3 2 -1216937469
. -
With
-O2
, I get the output of3 2 515
like you do, which makes union memory{3, 2, 0, 0}
. What happens is thatgcc
optimizes the call toprintf
with actual values, so the assembly output looks like an equivalent of:#include <stdio.h> int main() { printf("%d %d %d\n", 3, 2, 515); return 0; }
The value 515 can be obtained as other explained in other answers to this question. In essence it means that when
gcc
optimized the call it has chosen zeroes as the random value of a would-be uninitialized union.
Writing to one union member and reading from another usually does not make much sense, but sometimes it may be useful for programs compiled with strict aliasing.