12

我是 C++ 新手,很好奇编译器如何处理布尔值的惰性求值。例如,

if(A == 1 || B == 2){...}

如果 A 等于 1,是否曾经评估过 B==2 部分?

4

8 回答 8

22

不,B==2不评估该部分。这称为短路评估

编辑: 正如Robert C. Cartaino 正确指出的那样,如果逻辑运算符重载,则不会发生短路评估(已经说过,为什么有人会重载逻辑运算符超出了我的范围)。

于 2009-11-25T18:40:20.340 回答
20

除非||运算符重载,否则不会计算第二个表达式。这称为“短路评估”。

在逻辑 AND (&&) 和逻辑 OR (||) 的情况下,如果第一个表达式足以确定整个表达式的值,则不会计算第二个表达式。

在您上面描述的情况下:

if(A == 1 || B == 2) {...}

...第二个表达式将不会被计算,因为

TRUE || ANYTHING, 总是计算为TRUE.

同样地,

FALSE && ANYTHING, 总是评估为FALSE,因此该条件也会导致短路评估

几个快速笔记

  • 短路评估不适用于过载&&||操作员。
  • 在 C++ 中,您可以保证首先计算第一个表达式。有些语言不保证求值的顺序,VB 根本不做短路求值。了解您是否正在移植代码很重要。
于 2009-11-25T18:48:59.727 回答
1

不评估 B==2 部分。

当心! 不要在那里放 ++B==2 之类的东西!

于 2009-11-25T18:42:08.270 回答
1

C++ 将短路应用于布尔表达式求值,因此B == 2永远不会求值,编译器甚至可以完全忽略它。

于 2009-11-25T18:42:32.300 回答
1

编译器通过生成中间跳转来处理这个问题。对于以下代码:

if(A == 1 || B == 2){...}

编译为伪汇编器,可能是:

    load variable A
    compare to constant 1
    if equal, jump to L1
    load variable B
    compare to constant 2
    if not equal, jump to L2
L1:
    ... (complete body of if statement)
L2:
    (code after if block goes here)
于 2009-11-25T18:42:44.170 回答
1

正如詹姆斯所说,这是短路评估。懒惰的评估是完全不同的东西。

于 2009-11-25T18:44:39.550 回答
0

不,这不对。

与 相同&&,如果一个错误,它不会打扰评估另一个。

于 2009-11-25T18:40:59.823 回答
0

B == 2永远不会被评估。

有关详细信息,请参阅短路评估

于 2009-11-25T18:42:00.023 回答