什么时候是bool的右手表达a | = mayRun();被执行?

时间:2013-12-02 11:24:48

标签: c++ compiler-construction compound-assignment

假设代码段

bool a;
a = true;
a |= mayRun();

a = false;
a |= mayRun();

在哪种情况下执行mayRun()?

所有解释都告诉我,那     a |= b; 相当于     a = a | b;

但它不能与示例相同     arr[i++] |= b; 表示。

3 个答案:

答案 0 :(得分:7)

它将始终执行,因为短路不适用于按位运算(仅适用于&&||等逻辑运算。

请注意,这种误解会导致令人讨厌的错误 - 开发人员会认为存在短路但没有错误,并且所有表达式部分都会一直执行并且会改变程序逻辑。

答案 1 :(得分:5)

它总是被执行。请注意,a |= b确实是a = a | b的简写(仅评估a一次)。特别是,不是 a = a || b的简写。

这意味着它不提供布尔运算符的短路行为,因此始终会评估b

将这些速记赋值形式与bool变量一起使用是很危险的,正是因为语义不明显。 &=实际上更糟糕。比较一下:

int two() { return 2; }

int main()
{
  bool b = true;
  b = b && two();
  assert(b);  //OK
}

用这个:

int two() { return 2; }

int main()
{
  bool b = true;
  b &= two();
  assert(b);  //FAILS!!
  // b &= two(); was actually b = 1 & 2, which is 0 !
}

简而言之,避免将|=&=与布尔变量一起使用。

答案 2 :(得分:0)

  

在哪种情况下mayRun()正在执行?

它将永远执行。

也许您期望|=执行短路,但事实并非如此:仅在逻辑运算符&&||中发生,当结果可以从第一个操作数确定时。没有像||=这样的逻辑复合赋值运算符,因此在赋值表达式中永远不会发生短路。

  

所有解释都告诉我,a |= b;等同于a = a | b;

几乎;但是你所阅读的任何解释都错过了一个重要的细节。

  

但它不能与示例arr[i++] |= b;表示的相同。

确实存在差异,正如C ++ 11 5.17 / 7所规定的那样:

  

E1 op = E2形式的表达式的行为等同于E1 = E1 op E2 ,但E1只评估一次