【问题标题】:C++ if statement reorderingC++ if 语句重新排序
【发布时间】:2014-04-12 14:27:01
【问题描述】:

在我的 C++(假设这是 gcc)中,我执行以下操作:

bool prevCurve;
bool curveInside;
bool prevCurveIn
if (!(prevCurve && curveInside == prevCurveIn)){
...
}

编译器会这样优化吗:

bool prevCurve;
bool curveInside;
bool prevCurveIn
if (!prevCurve || curveInside != prevCurveIn){
...
}

【问题讨论】:

  • 为什么要优化?
  • 这取决于您的编译器、优化设置以及布尔值在何时何地获取它们的值(即,如果其中一个在您当前的范围内保持不变,它可能会完全消失 从等式)。
  • @LaszloPapp:在第一种情况下,必须检查比较的两个部分,理想情况下,在“优化”行中只有一个。
  • @Jongware:你什么意思?无论哪种方式,它都是三个操作:一个比较、一个否定和一个 OR/AND。
  • @LaszloPapp: 不,不是:) 在第二个例子中,如果prevCurvefalse,则第二部分不需要检查。

标签: c++ gcc optimization if-statement


【解决方案1】:

没有。评估此表达式时:

if (!(prevCurve && curveInside == prevCurveIn)){

该标准要求在评估表达式的其余部分之前对 prevCurve 进行完全评估,包括任何副作用。运算符 '&&' 引入了一个序列点。在等价的情况下:

if (!prevCurve || curveInside != prevCurveIn){

运算符|| 还引入了一个序列点。

理论上,编译器可能会在这两种情况下生成相同的代码,但即使这样,这也不是优化。撇开基于其他考虑的优化可能性不谈,每种情况下的代码都将执行相似的指令序列,结果完全相同。标准要求必须如此。

【讨论】:

  • 为了澄清,标准要求if后面的语句块要么在两种情况下都执行,要么在两种情况下都不执行;它对生成什么汇编代码或运行需要多长时间没有任何要求。
  • @MattMcNabb:但它确实对评估的顺序以及是否对 ||&& 都评估右侧提出了要求。
  • 是的,尽管在这个特定的示例中没有观察到该评估的影响(除非变量是易变的或未初始化的)。我的意思是说标准不需要生成类似的指令序列,即使这两个表达式保证具有完全相同的可观察行为
【解决方案2】:

这完全取决于您的编译器和周围的代码,但考虑到最常见的指令集,这毕竟不是优化。

原因是你有三个操作要执行:

  • 一个评估,变量或否定变量
  • 否定
  • 或/与

顺序可能不同,但必须执行这些点。我不知道有任何指令集可以优化另一个指令集。

正如评论中所写,如果变量具有常量值、您对 gcc 使用哪些优化选项、gcc 的版本、架构、不同的平台等,编译器甚至可以优化它们。

最好的方法是比较您可以生成的汇编器输出:

gcc -S main.cpp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    相关资源
    最近更新 更多