为什么这段代码没有产生严格别名警告?

5

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

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

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

但事实并非如此。我可以让警告在其他情况下打印出来,但我想知道为什么在这种情况下它没有打印出来。这不是一个明显的违反严格别名规则的例子吗?


2
... -Wstrict-aliasing=1 ... 产生警告。 - pmg
1个回答

2

GCC的-Wstrict-aliasing=2文档中说(重点在我这里):

等级2:激进,快速,不太精确。可能仍然有许多误报(虽然没有等级1多),而且假阴性较少(但可能比等级1多)。与等级1不同的是,它只在地址被取时发出警告。警告不完整类型。仅在前端运行。

看起来你的代码并不太复杂,所以我不确定为什么会有假阴性,但也许是因为你没有使用&地址运算符来执行别名操作(这可能是“只在地址被取时发出警告”的意思)。


更新:

这是由于未使用取地址运算符。如果我在foo.c文件中添加以下代码:

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

    foo( &myB);

    return 0;
}

警告已发出。

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


啊,现在这就有意思了。我之前错误地认为-Wstrict-aliasing=2是最高的警告级别。谢谢! - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接