This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
How to type-pun and why
- From: Mattias Engdegård <mattias at virtutech dot se>
- To: gcc-help at gcc dot gnu dot org
- Date: Mon, 12 Jun 2006 14:58:56 +0000 (UTC)
- Subject: How to type-pun and why
Some code I had needed to do integer operations on (the bits of)
floating-point values. The naive
double d = something;
uint64_t x = *(uint64_t *)&d;
gives a type aliasing diagnostic in 4.1, and rightly so. However,
attempting to "fix" this by adding an alias-anything intermediate
pointer to void or char,
uint64_t x = *(uint64_t *)(void *)&d;
suppresses the diagnostic but still won't work properly - gcc does not admit
that x depends on d, so the assignment of d sometimes ends up after that of x.
Using a union intermediate instead,
union { double d; uint64_t x; } u;
u.d = something;
uint64_t x = u.x;
works as expected, but I would like to know why - if it is a matter of luck
with the current implementation it might cease working when the compiler
changes or becomes more aggressive in the future.
As far as I can tell from the Standard, it could be argued that none
of the above versions are allowed at all, so it's not obvious to me
why one should be permitted but not another. I would be grateful for
any help with references.
The ABI for the platforms I am interested in give guarantees concerning the
representation and alignment of the types involved, of course.