4

我有以下代码:

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

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

4

1 回答 1

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()在单独的编译单元中,则不会发出警告。

于 2010-09-28T23:34:22.377 回答