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

发布于 2024-09-25 11:15:29 字数 645 浏览 1 评论 0原文

我有以下代码:

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

恬淡成诗 2024-10-02 11:15:29

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

第 2 级:积极、快速,但不过分
精确的。可能还是有很多假的
正面(没有 1 级那么多)
虽然),并且很少有假阴性(但是
可能超过级别 1)
。不像
级别 1,仅在地址出现时发出警告
被采取。警告不完整
类型。仅在前端运行。

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


更新:

这是由于不使用地址运算符所致。如果我将以下代码添加到 foo.c 文件中:

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

    foo( &myB);

    return 0;
}

会发出警告。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文