You did it:
union NumericType Values = { 10 }; // iValue = 10 printf("%d\n", Values.iValue); Values.dValue = 3.1416;
As the compiler uses memory for this union, it is similar to using the variable with the largest size and alignment (any of them, if there are several), and reinterpret the cast when one of the other types in the union is written or available, as in:
double dValue; // creates a variable with alignment & space // as per "union Numerictype Values" *reinterpret_cast<int*>(&dValue) = 10; // separate step equiv. to = { 10 } printf("%d\n", *reinterpret_cast<int*>(dValue)); // print as int dValue = 3.1416; // assign as double printf("%d\n", *reinterpret_cast<int*>(dValue)); // now print as int
The problem is that when you set dValue to 3.1416, you completely overwrite the bits you used to store number 10. The new value may seem like garbage, but it's just the result of interpreting the first (sizeof int) bytes of double 3.1416, assuming there will be useful value there int
If you want two things to be independent - so setting double does not affect a previously saved int, then you should use struct / class .
This may help you consider this program:
#include <iostream> void print_bits(std::ostream& os, const void* pv, size_t n) { for (int i = 0; i < n; ++i) { uint8_t byte = static_cast<const uint8_t*>(pv)[i]; for (int j = 0; j < 8; ++j) os << ((byte & (128 >> j)) ? '1' : '0'); os << ' '; } } union X { int i; double d; }; int main() { X x = { 10 }; print_bits(std::cout, &x, sizeof x); std::cout << '\n'; xd = 3.1416; print_bits(std::cout, &x, sizeof x); std::cout << '\n'; }
Which, for me, produced this conclusion:
00001010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10100111 11101000 01001000 00101110 11111111 00100001 00001001 01000000
The first half of each line shows 32 bits that are used for iValue: note that the binary code 1010 in the low byte value (on the left of an Intel processor such as mine) is 10 decimal. Writing 3.1416 changes all 64 bits to a pattern representing 3.1416 (see http://en.wikipedia.org/wiki/Double_precision_floating-point_format ). The old model 1010 is being rewritten, lost, electromagnetic memory no more.