为什么没有为此代码生成严格别名警告?

时间:2010-09-28 22:27:18

标签: c gcc c99 gcc-warning strict-aliasing

我有以下代码:

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");
    }
}

我正在使用以下命令行编译代码:

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

我正在使用GCC 4.5.0。我希望编译器打印出警告:

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

但它永远不会。我可以在其他情况下打印警告,但我想知道为什么,在这种情况下,它不是。这不是打破严格别名规则的明显例子吗?

1 个答案:

答案 0 :(得分:1)

GCC的-Wstrict-aliasing=2文档说(强调我的):

  

等级2:好斗,快速,不太好   精确。可能还有很多错误   积极因素(不及1级)   虽然)和很少的假阴性(但是   可能超过1级)。不像   级别1,它仅在地址时发出警告   被采取。警告不完整   类型。只在前端运行。

看起来你的代码并不太棘手,所以我不确定为什么会出现误报,但也许是因为你没有使用&地址运算符来执行别名(可能是“仅在收到地址时发出警告”的意思)


更新

来自不使用address-of运算符。如果我将以下代码添加到foo.c文件中:

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

    foo( &myB);

    return 0;
}

发出警告。

如果usefoo()位于单独的编译单元中,则不会发出警告。