假设代码片段
bool a;
a = true;
a |= mayRun();
a = false;
a |= mayRun();
在什么情况下执行 mayRun()?
所有的解释都告诉我,这
a |= b;
相当于
a = a | b;
但它不能与示例
arr[i++] |= b;
所示的相同。
假设代码片段
bool a;
a = true;
a |= mayRun();
a = false;
a |= mayRun();
在什么情况下执行 mayRun()?
所有的解释都告诉我,这
a |= b;
相当于
a = a | b;
但它不能与示例
arr[i++] |= b;
所示的相同。
它将始终执行,因为短路不适用于按位运算(仅适用于 and 等逻辑运算&&
)||
。
请注意,这种误解可能会导致严重的错误——开发人员会假设存在短路,但实际上并没有,并且所有表达式部分都始终执行,这会改变程序逻辑。
它总是被执行。请注意,这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 !
}
简而言之,避免将|=
and&=
与布尔变量一起使用。
在什么情况下
mayRun()
被执行?
它总是会被执行。
也许您期望|=
执行短路,但事实并非如此:这只发生在逻辑运算符&&
and||
上,当结果可以仅从第一个操作数确定时。没有像 一样的逻辑复合赋值运算符||=
,因此在赋值表达式中永远不会发生短路。
所有的解释都告诉我,这
a |= b;
相当于a = a | b;
几乎; 但是,无论您一直在阅读什么解释,都错过了一个重要的细节。
但它不能与示例
arr[i++] |= b;
所示的相同。
实际上,正如 C++11 5.17/7 所指定的那样,存在差异:
除了 E1 只计算一次之外,该形式的表达式的行为
E1 op = E2
等价于。E1 = E1 op E2