作为一个新手,我试图找出使用GCC优化标志时会发生什么。哪些优化标志可能产生副作用。我应该避免使用哪种特殊情况进行优化。我想优化可以打破一些多线程代码,但还有什么?
答案 0 :(得分:8)
编译器的优化通常会努力保留实现定义的行为(有一些例外,特别是对于未通过通用-O
标志启用的积极浮点优化)。换句话说,如果程序的功能行为因优化而发生变化,则程序可能正在调用 unspecified behavior 或 undefined behavior 。< / p>
您应始终避免编写调用未定义行为的程序,并确保未指定的行为不会影响程序的结果。问题不在于优化,而在于调用未定义的行为或给出未指定的行为有可能影响结果。如果更改编译器或编译器版本,即使您在没有优化的情况下继续编译,这些也会造成麻烦。
用措辞来回答你的问题:
优化可以使未初始化的变量同时显示为true and false,或者将未初始化的变量的产品显示为两个result into an odd value。只是不要使用未初始化的变量,因为这基本上是未定义的行为。
通过优化,带符号的算术溢出可能会导致类型int
的表达式显然具有大于INT_MAX
的值。使用优化编译的函数int f(int x) { return x+1 > x; }
在应用于1
时返回INT_MAX
。为了避免这种奇怪的行为,根本就不依赖于带符号的算术溢出,它是未定义的行为。
通过优化,可以同时悬挂指针be different and identical:根本不要使用悬空指针。
通过优化,可以在编译时计算调用未定义行为的常量表达式,其语义不同于在没有优化的情况下生成的汇编指令的运行时语义。对于大于类型大小的班次,预计会发生这种情况:使用32位int
,表达式1 >> 32
可以通过优化评估为0
,而不评估1
。 overflows in the conversion from floating-point to integer也可能发生同样的情况:它们也是未定义的行为。