And*_*rew 5 c gcc c99 strict-aliasing gcc-warning
我有以下代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下命令行编译代码:
gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c
Run Code Online (Sandbox Code Playgroud)
我正在使用海湾合作委员会4.5.0。我希望编译器打印出警告:
warning: dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
但事实并非如此。对于其他情况,我可以打印出警告,但我想知道为什么在这种情况下却没有打印出来。这不是违反严格别名规则的明显例子吗?
GCC 的文档-Wstrict-aliasing=2说(强调我的):
2 级:积极、快速,但不太精确。可能仍然有许多误报(尽管不如 1 级那么多),并且很少有误报(但可能超过 1 级)。与级别 1 不同,它仅在地址被占用时发出警告。关于不完整类型的警告。仅在前端运行。
看起来你的代码并不太棘手,所以我不确定为什么会出现漏报,但也许是因为你没有使用地址&运算符来执行别名(这可能就是这个意思)通过“仅在地址被占用时发出警告”)
更新:
这是因为没有使用地址运算符。如果我将以下代码添加到 foo.c 文件中:
int usefoo(void)
{
struct B myB = {0};
foo( &myB);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
发出警告。
如果usefoo()位于单独的编译单元中,则不会发出警告。