"if([bool] == true)"是否需要比"if([bool])多一步"?

Dan*_*Tao 28 optimization boolean

这是一个纯粹迂腐的问题,以满足自己的好奇心.

我倾向于在问题中使用后一种选择(所以if (boolCheck) { ... }:),而同事总是写前者(if (boolCheck == true) { ... }).我总是有点嘲笑他,并且从他第一次开始编程时他总是把它解释为一种旧习惯.

但是我今天刚刚想到,实际写出整个== true部分可能实际上需要一个额外的处理步骤,因为任何带有==运算符的表达式都会被计算为布尔值.这是真的?

换句话说,据我所知,没有 == true行的选项可以松散地描述如下:

  1. 检查X.

使用 == true行的选项更像是:

  1. 如果X为真,则Y为真,否则为假
  2. 检查Y.

我对么?或者也许任何普通的编译器/解释器都会消除这种差异?或者我忽略了什么,而且根本没有什么区别?

显然,在实际观察到的性能方面没有区别.就像我说的,我只是好奇.

编辑:感谢所有实际发布编译结果的人,以说明两种方法之间的步骤是否不同.(看起来,大部分时间,它们都是,虽然只是轻微的.)

我只想重申,我并不是在问什么是"正确的"方法.我知道很多人喜欢一个人而不是另一个人.我也理解,从逻辑上讲,两者是相同的.如果CPU执行的实际操作对于两种方法完全相同,我只是很好奇; 事实证明,在很多时候(显然它取决于语言,编译器等),它们不是.

rlb*_*ond 18

我认为与真实的比较表明你的伴侣缺乏理解.BOOLS应该命名事情,以避免这一点(如isAvaliable:if (isAvailable) {...}).


Luk*_*keH 16

我希望通过任何半合适的编译器来优化差异.

(我刚用C#检查过,两种语法的编译代码完全相同.)

  • @uncleo:这不是语言问题,而是特定编译器的问题. (3认同)
  • @stormsoul:这是一个语言问题.OP没有提到C#,这两个表达式在C或C++中不相同.当然,对于任何编译器,机器指令在这些语言中都是不同的. (2认同)

i_a*_*orf 13

编译器应该生成相同的代码.然而,与真实相比可以说更好,因为它更明确.一般来说,我不做明确的比较,但你不应该取笑他这样做.

编辑:最简单的方法是尝试.MS编译器(cl.exe)在汇编中生成相同数量的步骤:

int _tmain(int argc, _TCHAR* argv[])
{
    bool test_me = true;

    if (test_me) {
004113C2  movzx       eax,byte ptr [test_me] 
004113C6  test        eax,eax 
004113C8  je          wmain+41h (4113E1h) 
        printf("test_me was true!");
    }

    if (test_me == true) {
004113E1  movzx       eax,byte ptr [test_me] 
004113E5  cmp         eax,1 
004113E8  jne         wmain+61h (411401h) 
        printf("still true!");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此时问题是做测试和cmp有相同的成本吗?我的猜测是肯定的,尽管专家可能会指出差异.

实际结果是你不应该担心这一点.你可能有更大的性能鱼炒.

  • 我认为(并且有)明确的比较没有任何好处并且可能导致微妙的错误(当然取决于语言):http://stackoverflow.com/questions/356217/should-i-use-isgood - 或isgood假/ 356709#356709 (9认同)
  • 我同意@Michael Burr - 避免明确比较.充其量,在某些语言中,它是对错误的邀请,例如,如果编译器允许构造,则将"if(check == true)"错误拼写为"if(check = true)". (7认同)
  • 不同意 - 它不是"更明确".这是多余的 - 您不需要在布尔表达式中指定"== true".这样做是一个"代码味道",表明程序员并不真正知道布尔表达式是如何工作的. (7认同)
  • 这只是一个MSVC实现细节,其他编译器也可能采用不同的方式.不过,有些人在谈论这个特定汇编代码的效率.是的,CMP和TEST几乎在所有CPU上都需要1个时钟周期 - 因此代码是等效的.所有版本的条件跳转指令在性能上也是等效的.我想指出的一个很小的细节是CMP指令长1个字节,这使得第二个代码稍微大一点:).不过,这是一个微不足道的差异. (6认同)
  • 但步骤不一样.一个使用test和je,另一个使用cmp和jne.我认为je和jne会有相同的表现,但我不知道test和cmp之间的区别. (2认同)

Mic*_*urr 10

重复的问题(我应该使用`!IsGood`或`IsGood == false`?).这是我之前回答的指针:

如果有问题的变量确实被用作布尔值(即使它的类型不是布尔值),那么专门针对true或false进行测试的技术是不好的做法 - 特别是在C/C++中.针对true can(并且可能会)的测试会导致细微的错误.

有关详细信息,请参阅以下SO答案:

我应该使用`!IsGood`还是`IsGood == false`?

这是一个详细说明为什么"== true"在更明确的细节中经常是错误的原因,包括Stroustrup的解释:https: //qt-project.org/forums/viewthread/32642


pet*_*hen 5

根据我的经验,if (flag==true)这是不好的做法。

第一个论点是学术性的:

如果有 a bool flag,则它是truefalse

现在,表达

(flag==true)
Run Code Online (Sandbox Code Playgroud)

再说一次,是truefalse——它并不更具表现力,只是多余——flag无法比现在变得“更真实”或“更虚假”。只有当布尔值不明显时,它才会“更清晰” flag- 但有一个标准方法可以修复适用于所有类型的问题:选择一个更好的名称

如果将其延伸到超出合理范围,以下内容将“甚至更好”:

((flag==true)==true)
Run Code Online (Sandbox Code Playgroud)

第二个论点是务实且特定于平台的

C 和早期的 C++ 实现没有真正的“bool”类型,因此标志有不同的约定,最常见的是任何非零的内容都是 true。API 返回基于整数的 BOOL 类型但不强制返回值为 0 或 1 的情况并不罕见。

某些环境使用以下定义:

#define FALSE 0
#define TRUE (!FALSE)
Run Code Online (Sandbox Code Playgroud)

祝你好运if ((1==1) == TRUE)

此外,某些平台使用不同的值 - 例如,VARIANT_BOOLVB 互操作的 是 a short,并且VARIANT_TRUE-1

当使用这些定义混合库时,与 true 的显式比较很容易成为伪装成良好意图的错误。所以,不要。