VS2008 c ++编译器会优化以下if语句吗?

时间:2009-12-16 00:52:13

标签: c++ optimization compiler-construction coding-style code-readability

if (false == x) { ...}

而不是:

if (!x) { ... }

if (false == f1()) { ...}

而不是:

if (!f1()) { ... }

我认为if(假= = ......版本更具可读性。你同意,或者你可以提出另一个技巧吗?它会一样快吗?谢谢。

这就是我不喜欢的原因!x:

if (25 == a->function1(12345, 6789) &&
    45 == b->function1(12345, 6789) &&
    !c->someOtherFunction(123)) { ... }

以下似乎更好:

if (25 == a->function1(12345, 6789) &&
    45 == b->function1(12345, 6789) &&
    false == c->someOtherFunction(123)) { ... }

6 个答案:

答案 0 :(得分:7)

我个人觉得表格if (!x) { ... }最具可读性,但现在它们都会产生相同的代码。

编辑:在您的示例中,我将执行以下操作:

if (  a->function1(12345, 6789) == 25 &&
      b->function1(12345, 6789) == 45 &&
    !(c->someOtherFunction(123))) { ... }

但这真的只是个人偏好的事情。做你最可读的事情。它不会有任何区别。

答案 1 :(得分:7)

  

我认为if(false == ...版本更具可读性。你同意,或者你可以提出另一个技巧?

你做错了。

false == x返回一个bool,显然必须与true进行比较!

if (true == (false == x)) { ...}会更好。但是这又一次回归了bool,所以为了安全起见,让你的代码更具可读性,我们最好这样做:

if (true == (true == (false == x))) { ...}。等等。一旦你开始将布尔值与布尔值进行比较,你会在哪里停止?结果总是另一个布尔值,为了保持一致,你必须将它与布尔值进行比较。

或者您可以学会理解您正在使用的语言,并使用if (!x) { ...},它会准确表达您想要的内容。

您认为哪个更具可读性?

  • if (false == x) { ...}转换为“如果false等于x则为真”。
  • if (!x) { ...}会转换为“if x not true”。

老实说,真的,真的说第一种形式“更具可读性”吗?你能用一句话说吗? “如果false等于x,那么这是真的吗?”

它不是更具可读性,它只是向任何读取代码的程序员喊叫“我不理解语句或布尔值”。

答案 2 :(得分:4)

C ++在左侧保留以下关键字作为右侧运营商的替代方案:

and  and_eq  bitand    &&  &=  &
or   or_eq   bitor     ||  |=  |
     xor_eq  xor           ^=  ^
not  not_eq  compl     !   !=  ~

如果您担心!迷路,not更突出。

if (    a->function1(12345, 6789) == 25 and
        b->function1(12345, 6789) == 45 and
        not c->someOtherFunction(123)) {
    ...
}

答案 3 :(得分:3)

一个好的编译器应该为两个代码块生成相同的代码。

但是,您不应该担心false == f1()!f1(),而应该更担心此示例中的短路评估:

if (25 == a->function1(12345, 6789) &&
    45 == b->function1(12345, 6789) &&
    !c->someOtherFunction(123)) { ... }

某些编译器将生成将跳过执行b->function1()c->someOtherFunction()的代码,如果a->function1()调用恰好评估为不同于25的内容 - 原因是编译器已经知道此时整个if ()语句的结果,所以它可以跳到正确的位置。

如果你的代码依赖于被任何跳过的函数修改的状态,你可能会得到令人讨厌的惊喜。

答案 4 :(得分:2)

这是一个过早优化的案例(When is optimisation premature?)。但编译器将生成相同的代码(MSVC 2008调试模式):

if (!bVal)
    bVal = true;

if (bVal == false)
    bVal = true;

//translates to

; 70   :         if (!bVal)

cmp BYTE PTR $T5793[ebp], 0
jne SHORT $LN9@wmain
push    OFFSET $LN10@wmain
call    __RTC_UninitUse
add esp, 4
$LN9@wmain:
movzx   eax, BYTE PTR _bVal$[ebp]
test    eax, eax
jne SHORT $LN2@wmain

; 71   :             bVal = true;

mov BYTE PTR $T5793[ebp], 1
mov BYTE PTR _bVal$[ebp], 1
$LN2@wmain:

; 72   :         
; 73   :         if (bVal == false)

cmp BYTE PTR $T5793[ebp], 0
jne SHORT $LN11@wmain
push    OFFSET $LN10@wmain
call    __RTC_UninitUse
add esp, 4
$LN11@wmain:
movzx   eax, BYTE PTR _bVal$[ebp]
test    eax, eax
jne SHORT $LN1@wmain

; 74   :             bVal = true;

mov BYTE PTR $T5793[ebp], 1
mov BYTE PTR _bVal$[ebp], 1

答案 5 :(得分:1)

你有没有想过并发现评估条件是一个热点?如果没有,那么请执行您的编码标准要求。

无论如何都应该编译成相同的代码。您可以通过检查编译器为两种情况生成的汇编代码进行检查。