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

How can compiler optimizations affect code logic?

本文关键字:代码 影响 优化 何影响 编译器      更新时间:2023-10-16

当相同的代码被完全禁用(g++ -O0),然后再次启用了优化(g++ -O3)时,如何才能更改源代码本身的逻辑?

例如,编译器可以

  • 放松循环和
  • 做恒定的折叠。

这两个优化使代码执行速度更快,而不会影响原始源代码的完整性。任何没有这些优化的没有这些优化的代码将随着它们启用。

但是,编译器优化也会影响代码逻辑。这是我知道的两个示例:

  • 从临时人员中删除复制构造函数和分配运算符可能会删除可能的副作用。
  • 重新安排包含浮点值的算术可能会影响浮点错误(希望需要-ffast-math参数)。

我很惊讶,很幸运地了解到这些,因为它们在错误的情况下可能会变得巨大的潜力。

所以我想知道,还有其他情况,C 编译器优化会影响代码逻辑吗?我专门在G 编译器下寻找有关C 11(没有任何未定义行为)的信息,但是欢迎其他编译器的提示。

;规则:

实施可以自由地无视此要求只要结果就好像要求从可观察到的程序的行为。例如,实际实施需要如果可以推断出其价值是未使用,没有影响可观察到的行为的副作用该程序是生产的。

但是,该标准提到了一个允许的优化,并打破了"如果"规则:

满足某些条件时,允许实现省略即使复制/移动对象的构造函数和/或破坏者具有副作用。 in在这种情况下,实施对待省略复制/移动操作只是两种不同的推荐方式到同一对象,该物体的破坏发生在后来的两个物体将被摧毁没有优化。123复制/移动操作的这种省略,在以下情况下允许称为复制省略(可以合并以消除多个副本):

- 回报具有类返回类型的函数中的语句,当表达式是非易失性自动对象的名称(功能除外或带有相同Cvunqualififific类型的catch子句参数)功能返回类型,可以省略复制/移动操作将自动对象直接构建到函数的返回中值

- 在抛出表达中,当操作数是一个名称时非挥发性自动对象(功能或捕获条件除外参数)的范围不会超出最内向的末端封闭了try-block(如果有一个),将复制/移动操作从异常对象(15.1)的操作数可以省略将自动对象直接构造到异常对象

- 当尚未绑定到参考的临时类对象(12.2)将被复制/移至具有相同的类对象CV UNQUALIFIED类型,可以省略复制/移动操作将临时对象直接构建到目标的目标中省略复制/移动

- 当异常的例外情况处理程序(第15条)声明了相同类型的对象(除了cv-qualification)作为异常对象(15.1),副本/移动可以通过将异常陈述视为一个,可以省略操作如果程序的含义为除了执行构造函数和破坏器的执行由异常解释声明的对象。

"未指定的行为"是行为,可以自由选择任何可能的行为。在这种情况下,优化器可能会影响选择的选择。

一个简单的示例是评估函数参数的顺序。非优化的构建物可以使用从左到右或左右,而优化的构建可能会以"混合"顺序评估参数。一个充分的理由是最大限度地利用参数之间的常见次级表达优化的机会。

如果这些参数中的任何一个具有明显的副作用,则代码逻辑将被更改,但是这是否是case to Case的错误。