编译器优化如何影响代码逻辑?

Rya*_*yan 6 c++ g++ compiler-optimization c++11

当使用完全禁用(g++ -O0)的优化编译同一段代码,然后再次完全启用优化(g++ -O3)时,源代码本身的逻辑如何改变?

例如,编译器可以

这两个优化使代码执行速度更快,而不会影响原始源代码的完整性.没有这些优化运行的任何代码都将在启用它们的情况下运行.

但是,编译器优化也会影响代码逻辑.以下是我所知道的两个例子:

我很惊讶,很幸运,了解这些因为他们可能在错误的情况下成为巨大的潜在陷阱.

所以我想知道,有没有其他情况下c ++编译器优化会影响代码逻辑?我特意在g ++编译器下查找有关c ++ 11(没有任何未定义的行为)的信息,但欢迎提供其他编译器的提示.

Dav*_*vid 8

"as-if"规则:

只要可以从程序的可观察行为中确定,结果就好像符合要求,实施可以自由地忽略本国际标准的任何要求.例如,实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用,并且没有产生影响程序的可观察行为的副作用.

但是,标准提到了一个允许的优化,它打破了"as-if"规则:

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使该对象的复制/移动构造函数和/或析构函数具有副作用.在这种情况下,实现将省略的复制/移动操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象的后期时间.在没有优化的情况下销毁.123在下列情况下允许复制/移动操作(称为复制省略)的这种省略(可以合并以消除多个副本):

- 在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cvunqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作

- 在throw-expression中,当操作数是非易失性自动对象的名称(函数或catch子句参数除外),其范围不会超出最内层封闭try-block的末尾(如果有的话)一),通过将自动对象直接构造到异常对象中,可以省略从操作数到异常对象(15.1)的复制/移动操作

- 当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到该对象中来省略复制/移动操作.省略的复制/移动的目标

- 当异常处理程序的异常声明(第15条)声明一个相同类型的对象(cv-qualification除外)作为异常对象(15.1)时,可以通过处理异常声明来省略复制/移动操作如果除了为exception-declaration声明的对象执行构造函数和析构函数之外,程序的含义将保持不变,则作为异常对象的别名.