C++ bool a |=mayRun()的右手表达式是什么时候;被处决?
假设代码片段C++ bool a |=mayRun()的右手表达式是什么时候;被处决?,c++,compiler-construction,compound-assignment,C++,Compiler Construction,Compound Assignment,假设代码片段 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代码>
指示。由于短路不适用于按位操作(仅适用于逻辑操作,如&&
和|
)
请注意,这种误解可能会导致严重错误-开发人员会假设存在短路,但没有短路,并且所有表达式部分都会一直执行,这会改变程序逻辑。因为短路不适用于按位操作,所以始终会执行短路(仅适用于逻辑操作,如&&
和| |
)
请注意,这种误解可能会导致严重错误-开发人员会假设存在短路,但没有短路,并且所有表达式部分都会一直执行,这会改变程序逻辑。它总是被执行。请注意,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 !
}
简而言之,避免对布尔变量使用|=
和&=
。它总是被执行。注意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 !
}
简而言之,避免对布尔变量使用|=
和&=
在哪种情况下执行mayRun()
它将永远被执行
也许您希望|=
执行短路,但事实并非如此:这只发生在逻辑运算符&&&
和|
上,此时结果只能由第一个操作数确定。没有像| 124;=
这样的逻辑复合赋值运算符,因此短路永远不会发生n赋值表达式
所有的解释都告诉我,a |=b;
等同于a=a | b;
差不多;但无论你读了什么解释,都漏掉了一个重要的细节
但它不能与arr[i++]|=b;
所示的示例相同
事实上,正如C++11 5.17/7所规定的那样,有一个区别:
形式为E1 op=E2
的表达式的行为等同于E1=E1 op E2
,只是E1只计算一次
在哪种情况下执行mayRun()
它将永远被执行
也许您希望|=
执行短路,但事实并非如此:这只发生在逻辑运算符&&&
和|
上,此时结果只能由第一个操作数确定。没有像| 124;=
这样的逻辑复合赋值运算符,因此短路永远不会发生n赋值表达式
所有的解释都告诉我,a |=b;
等同于a=a | b;
差不多;但无论你读了什么解释,都漏掉了一个重要的细节
但它不能与arr[i++]|=b;
所示的示例相同
事实上,正如C++11 5.17/7所规定的那样,有一个区别:
形式为E1 op=E2
的表达式的行为等同于E1=E1 op E2
,只是E1只计算一次
@nvoigt这将给出一个模编译器错误和特性的答案。对于性能问题,“profile it”是正确的答案。对于“这里应该发生什么”问题,我会小心“proof by compiler”关于最后两句话,除了a
只计算一次之外,它是等价的。@nvoigt这将给出一个关于模编译器错误和特性的答案。对于性能问题,“profile it”是正确的答案。对于“这里应该发生什么”问题,我会小心“编译器证明”关于最后两句话,除了a
只评估一次之外,它是等效的。谢谢,这正是我需要的解释级别:-)谢谢,这正是我需要的解释级别:-)