
Le mardi 26 février 2008 à 14:04 +0000, John Maddock a écrit :
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. The suggestion in the article is to use a union to move from one type to another:
(I have not read the article, so perhaps the following was already discussed there.) Using an union this way also breaks strict aliasing. Fortunately, at least for GCC, this breakage is explicitly documented as being an extension supported by the compiler. So it is guaranteed to work just fine. But I don't know if it is also a documented feature for other compilers, or if it may break once they strengthen their optimization algorithms. You were concerned with calling memcpy, but at least for GCC, the compiler recognizes this function. As a consequence, it does not perform any memory copy at all and directly moves data from integer registers to float registers, if permitted by the processor. So the generated code is optimal (or at least not worse than what the compiler usually generates). Again, I have no idea how other compilers behave. Summary: With GCC, both the union and the memcpy generates the exact same assembly code. Both are documented as being supported. But the second one is the only one that is compliant with the C++ standard. Best regards, Guillaume