I wanted to learn more about type punning and aliasing. So I use the code provide by the GCC documentation at option -fstric-aliasing
like below :
union a_union{
int i;
double d;
};
int f(){
union a_union t;
t.d=3.0;
return t.i
}
/*what I add*/
int main(int argc, char *argv[])
{
printf("%d\n",f());
return 0;
}
I expected nothing special but I get only 0. So I test with different value for t.d
but no change.
I test this code on Debian 9, with gcc 6.3, without option.
I also try with option -fno-strict-aliasing
same result
If someone can I explain, why I get only 0 that would be great
The sizes of the members do not match in any common systems. int
is usually nowadays 32 bits and double
64 bits. Because of little-endian storage, the zero bits at the end of the 3.0000000000
correspond to those of the int
member.
Try this one instead:
#include <inttypes.h>
#include <stdio.h>
union q_union{
uint64_t i;
double d;
};
_Static_assert(sizeof (union q_union){}.i == sizeof (union q_union){}.d,
"The sizes of double and uint64_t must match");
uint64_t f(void) {
union q_union t;
t.d = 3.0;
return t.i;
}
int main(int argc, char *argv[])
{
printf("%" PRIu64 "\n", f());
printf("%#" PRIx64 "\n", f());
return 0;
}
outputs:
4613937818241073152
0x4008000000000000