红色部分代码在gcc开启-fstrict-aliasing选项后将得到错误的代码。由于使用了type-punned pointer将打破strict-aliasing规则。
由于-fstrict-aliasing选项在-O2, -O3, -Os等优化模式下都将开启(目前dev不带优化,main带-O3所以该问题只在main上出现)所以建议对linux编译中产生
warning: dereferencing type-punned pointer will break strict-aliasing rule
警告的情况作为编译失败。以便防止出现类似问题。
上述代码应当使用联合体重写为:
这样就不会打破该规则。
什么是Strict Aliasing?请看:http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html?
In C99, it is illegal to create an alias of a different type than the original.
在我们现在的代码中可以按正则表达式\([^()]+\*:b*\):b*&找到约180个匹配行,涉及60个文件。
这其中应该有一些是不符合这个strict-aliasing要求的。
处理方法
1是临时关闭strict-aliasing选项:在使用-O2, -O3, -Os编译的情况下使用-fno-strict-aliasing关闭strict-aliasing
2是要修改这类不满足该限制的代码,在完全修改完毕之后再打开。
要注意到,strict-aliasing选项提示编译器代码满足这个限制,所以可以提供编译器进行额外的代码优化的机会。