views:

79

answers:

1

I have the following code:

struct A
{
    short b;
};

struct B
{
    double a;
};


void foo (struct B* src)
{
    struct B* b = src;
    struct A* a = (struct A*)src;

    b->a = sin(rand());

    if(a->b == rand())
    {
        printf("Where are you strict aliasing warnings?\n");
    }
}

I'm compiling the code with the following command line:

gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c

I'm using GCC 4.5.0. I expected the compiler to print out the warning:

 warning: dereferencing type-punned pointer will break strict-aliasing rules

But it never is. I can get the warning to be printed out for other cases, but I'm wondering why, in this case, it isn't. Is this not an obvious example of breaking the strict aliasing rules?

+1  A: 

GCC's docs for -Wstrict-aliasing=2 says (emphasis mine):

Level 2: Aggressive, quick, not too precise. May still have many false positives (not as many as level 1 though), and few false negatives (but possibly more than level 1). Unlike level 1, it only warns when an address is taken. Warns about incomplete types. Runs in the frontend only.

It seems like your code isn't too tricky, so I'm not sure why there'd be a false negative, but maybe it's because you don't use the & address-of operator to perform the aliasing (that might be what's meant by "only warns when an address is taken")


Update:

It is from not using the address-of operator. If I add the following code to the foo.c file:

int usefoo(void)
{
    struct B myB = {0};

    foo( &myB);

    return 0;
}

The warning is issued.

If usefoo() is in a separate compilation unit, no warning is issued.

Michael Burr
Ah yes, this makes sense now. I was incorrectly thinking -Wstrict-aliasing=2 was the highest warning level. Thanks!
Andrew