public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* strict aliasing rule and examples
@ 2008-02-26 15:33 Mojmir Svoboda
  2008-02-26 19:20 ` Andrew Haley
  0 siblings, 1 reply; 2+ messages in thread
From: Mojmir Svoboda @ 2008-02-26 15:33 UTC (permalink / raw)
  To: gcc-help

hello,
i've just encountered some code breaking the aliasing rule:

#include <cstdio>

unsigned EndianSwap (unsigned data) {
    return (data << 24 & 0xff000000) | (data << 8 & 0x00ff0000)
        | (data >> 8 & 0x0000ff00) | (data >> 24 & 0x000000ff);
}
float EndianSwap (float data) {
    unsigned res = EndianSwap(*reinterpret_cast<const unsigned *>(&data));
    return *reinterpret_cast<float*>(&res);
}
int main () {
    float aa = 123.456f;
    float bb = EndianSwap(aa);
    printf("swap: %f -> %f\n", aa, bb);
}

the thing is that i can see what happens if -O3 and -fstrict-aliasing
is on, but i'd like to know what's going on under-the-hood (if it is
almost-human explainable):
i mean - what is compiler doing to optimize the whole swap code out?


and yet another (perhaps related) thing: let's have following code:

struct vect {
  float x, y, z;
  float & operator[] (int i) { return *(&x + i); }
};

i know that there is a potential hazard with padding, but
gcc guru of mine told me that this is in fact breaking of the aliasing
rule too, but after few beers i stopped following his arguments.
is it? how does it break the rule? or is this code dangerous in any
other way?

thanks for your attention,
mojmir

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: strict aliasing rule and examples
  2008-02-26 15:33 strict aliasing rule and examples Mojmir Svoboda
@ 2008-02-26 19:20 ` Andrew Haley
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Haley @ 2008-02-26 19:20 UTC (permalink / raw)
  To: Mojmir Svoboda; +Cc: gcc-help

Mojmir Svoboda wrote:
> hello,
> i've just encountered some code breaking the aliasing rule:
> 
> #include <cstdio>
> 
> unsigned EndianSwap (unsigned data) {
>     return (data << 24 & 0xff000000) | (data << 8 & 0x00ff0000)
>         | (data >> 8 & 0x0000ff00) | (data >> 24 & 0x000000ff);
> }
> float EndianSwap (float data) {
>     unsigned res = EndianSwap(*reinterpret_cast<const unsigned *>(&data));
>     return *reinterpret_cast<float*>(&res);
> }
> int main () {
>     float aa = 123.456f;
>     float bb = EndianSwap(aa);
>     printf("swap: %f -> %f\n", aa, bb);
> }
> 
> the thing is that i can see what happens if -O3 and -fstrict-aliasing
> is on, but i'd like to know what's going on under-the-hood (if it is
> almost-human explainable):

If you are to understand this at all, you *must* read the appropriate
section of the ISO C standard.  This is Section 6.3.2.3.  Search for
iso-9899 on the web.  This section tells you which pointer conversions are
defined, and any pointer conversion not defined in that section has no
meaning.

> i mean - what is compiler doing to optimize the whole swap code out?

The code is meaningless, so the compiler doesn't have to do anything
at all.  What actually happens is that the compiler can see that the 
statements have no effect, so the whole lot gets dropped on the floor.

> and yet another (perhaps related) thing: let's have following code:
> 
> struct vect {
>   float x, y, z;
>   float & operator[] (int i) { return *(&x + i); }
> };
> 
> i know that there is a potential hazard with padding, but
> gcc guru of mine told me that this is in fact breaking of the aliasing
> rule too, but after few beers i stopped following his arguments.
> is it? how does it break the rule?

It's not one of the well-defined conversions in Section 6.3.2.3.

Basically, the rule is this: you cannot take the address of an object
and through pointer type conversion create an lvalue of an incompatible
type.

gcc has a useful extension, which is supported my many compilers:

float EndianSwap (float data) {
   union
   {
     float fd;
     unsigned ud;
   } u;
   u.fd = data;
   u.ud = EndianSwap(u.ud);
   return u.fd;
}


This is much nicer anyway, and it much more clearly describes what you're
trying to do.

Andrew.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-02-26 17:44 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-26 15:33 strict aliasing rule and examples Mojmir Svoboda
2008-02-26 19:20 ` Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).