Boost logo

Boost :

From: Guillaume Melquiond (guillaume.melquiond_at_[hidden])
Date: 2008-02-26 10:02:17


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_aliasing.html
>
> >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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk