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

问题描述 投票:0回答:6
if (false == x) { ...}

相对于:

if (!x) { ... }

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

相对于:

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

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

这就是我不喜欢的原因!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)) { ... }
c++ optimization coding-style code-readability
6个回答
7
投票

我个人认为

if (!x) { ... }
的形式最具可读性,但现在它们都会产生相同的代码。

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

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

但这实际上只是个人喜好的事情。做对你来说最易读的事情。这不会有任何区别。


7
投票

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

你做错了。

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

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

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

或者您可以学习理解您正在使用的语言,并使用

if (!x) { ...}
,它准确地表达了您想要的内容。

您认为哪一个更具可读性?

  • if (false == x) { ...}
    翻译为“如果 true 则 false 等于 x”。
  • if (!x) { ...}
    翻译为“如果 x 不为真”。

你能诚实、认真地说第一种形式“更具可读性”吗?你会用一句话来这么说吗? “如果 true 则 false 等于 x”?

它并没有更具可读性,它只是向任何阅读你的代码的程序员大喊“我不明白 if 语句或布尔值”。


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
投票

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

但是,您应该更担心此示例中的短路评估,而不是担心

false == f1()
!f1()

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

如果

b->function1()
调用的计算结果恰好不同于 25,某些编译器将生成跳过
c->someOtherFunction()
a->function1()
执行的代码 - 原因是,编译器已经知道整个
if ()
的结果在那一点上声明,这样它就可以跳转到正确的位置。

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


2
投票

这是过早优化的一个例子(什么时候优化过早?)。但编译器会生成相同的代码(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

1
投票

您是否已分析并发现评估病情是一个热点? 如果没有,则执行您的编码标准要求的任何操作。

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

© www.soinside.com 2019 - 2024. All rights reserved.