假设代码段
bool a;
a = true;
a |= mayRun();
a = false;
a |= mayRun();
在哪种情况下执行mayRun()?
所有解释都告诉我,那
a |= b;
相当于
a = a | b;
但它不能与示例相同
arr[i++] |= b;
表示。
答案 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只评估一次。