Here goes the first code:
#include<stdio.h>
int main(){
union var{
int a;
int b;
};
union var v;
v.b=10;
v.a=5;
printf("%d", v.b);
return 0;
}
This gives 5 as the output.
However, consider this code:
#include<stdio.h>
int main(){
union var{
int a;
float b;
};
union var v;
v.b=10.0;
v.a=5;
printf("%f", v.b);
return 0;
}
This gives 0.000000 as the output.
Any explanations?
Bits in memory are used to represent different types in different ways. This answer discusses the representations used most commonly for int
(32-bit two’s complement) and float
(IEEE-754 binary32, also called single precision), assuming there are no complications with padding bits or different ordering of bits and bytes between int
and float
.
For int
, there is a sign bit and 31 value bits. The 31 value bits are interpreted as a binary numeral. The sign bit represents the value −231, and the value represented by the int
is the sum of the value of the sign bit and the value of the binary numeral.
When you store 5 in the int
member v.a
, 5 is represented with the sign bit 0 and value bits 0000000000000000000000000000101. When you read it with int
member v.b
, the bits are interpreted in the same way they were used to represent 5, so the result is 5.
When you read it with float
member v.b
, the bits are reinterpreted using the scheme for float
.
For float
, there is a sign bit s, 8 exponent bits e, and 23 significand bits f, where e and f are the values of the bits when interpreted as binary numerals. These bits are interpreted as:
When the bits 00000000000000000000000000000101 are interpreted as a float
, then s is 0, e is 0, and f is 5. This fits the first condition, so the value represented is (−1)0•21-127•(0+5/223) = 2−126•5•2−23 = 5•2−149, which is approximately 7•10−45.
When you print this number with %f
, it is so small that only “0.000000” is printed. If you print it with %g
, the output will be “7.00649e-45”.
Note that, in C, reading the value of a member other than the last one written reinterprets the bytes of memory as the new type, per C 2018 6.5.2.3 3 and note 99. In C++, the behavior is not defined.