use*_*106 8 c gcc strict-aliasing
关于类型双关语的问题:为什么这段代码会破坏严格的别名规则:
int main()
{
int a = 1;
short j;
printf("%i\n", j = *((short*)&a));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这不是:
int main()
{
int a = 1;
short j;
int *p;
p=&a;
printf("%i\n", j = *((short*)p));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
建设者gcc -fstrict-aliasing.
谢谢!
Sha*_*our 11
他们都违反了严格的别名规则,我将在这里引用我的答案(强调我的前进):
代码违反了严格的别名规则,这使得通过不同类型的指针访问对象是非法的,尽管允许通过char*进行访问.允许编译器假设不同类型的指针不指向相同的存储器并相应地进行优化.
gcc在-Wstrict-aliasing=n 这里的文件中更详细一点说:
此选项仅在-fstrict-aliasing处于活动状态时处于活动状态.它会警告可能会破坏编译器用于优化的严格别名规则的代码.更高的级别对应于更高的准确性(更少的误报).更高的级别也相应于更多的努力,类似于-O的工作方式.-Wstrict-aliasing相当于-Wstrict-aliasing = 3.
并描述每个级别如下:
1级:最具攻击性,快速,最不准确.当更高级别不警告但-fstrict-aliasing仍然会破坏代码时可能很有用,因为它几乎没有错误否定.但是,它有许多误报.警告可能不兼容的类型之间的所有指针转换,即使从未解除引用.仅在前端运行.
等级2:积极,快速,不太精确.可能仍有许多误报(尽管不是1级),也没有假阴性(但可能超过1级).与级别1不同,它仅在发出地址时发出警告.警告不完整的类型.仅在前端运行.
级别3(-Wstrict-aliasing的默认值):应该具有非常少的误报和很少的误报.启用优化后,比级别1或2略慢.注意前端常见的双关语和解除引用模式:
*(int*)&some_float.如果启用了优化,它也会在后端运行,它使用流敏感点来处理多个语句案例.仅在取消引用转换后的指针时发出警告.不警告不完整的类型.
因此不能保证捕获所有实例,不同级别具有不同程度的准确性.
通常,您正在寻找的效果可以通过联合使用类型惩罚来完成,我在上面的链接答案中介绍了gcc明确支持的.