
John Maddock wrote:
Sorry to bring this up again (!), but I've been trying to get my head around the aliasing rules and what is and isn't allowed, in particular by following the rather useful article here: http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_alias...
From this it appears that your current code is perfectly fine, however I still can't help feeling that we could do better than call an external function (memcpy) to move 4 or 8 bytes.
When you compile on Visual Studio, with the compiler option /Oi (or /O2), then the compiler treats memcpy as a compiler intrinsic (i.e. essentially as a key word) and not as an external function; see http://msdn2.microsoft.com/en-us/library/tzkfha43.aspx I looked at assembler output a year ago, and, if I remember right, a memcpy of four bytes was compiled to a single move instruction. The suggestion in the article is to
use a union to move from one type to another:
union float_to_int32 { float f; boost::uint32_t i; };
boost::uint32_t get_bits(float f) { float_to_int32 u; u.f = f; return u.i; }
I can't claim to have tested exhaustively, but modifying get_bits and set_bits to use this method seems to work OK for VC8&9 and Minwg GCC.
Interesting, but I wouldn't do this without the approval of a pedantic langauge lawyer. I have been bitten by this sort of things in the past. And I'm not sure it would make things faster on Visual Studio anyway. --Johan