有什么理由不对C++中的"bool“值使用按位运算符&、|和^吗?
我有时会遇到希望两个条件中的一个条件为真(XOR)的情况,所以我只是将^运算符抛入条件表达式中。有时,我还希望评估条件的所有部分是否为真(而不是短路),因此我使用&和|。我有时还需要累加布尔值,而&=和|=可能非常有用。
在这样做的时候,我遇到了一些令人惊讶的问题,但代码仍然是有意义的,而且比不这样做更干净。有什么理由不将这些用于bools吗?有没有现代的编译器会对此产生不好的结果?
发布于 2008-08-23 12:06:20
||
和&&
是布尔运算符,内置的运算符保证返回true
或false
。没别的了。
|
、&
和^
都是按位运算符。当您操作的数字域只有1和0时,它们是完全相同的,但在布尔值不是严格意义上的1和0的情况下-就像C语言的情况一样-您可能会得到一些您不想要的行为。例如:
BOOL two = 2;
BOOL one = 1;
BOOL and = two & one; //and = 0
BOOL cand = two && one; //cand = 1
然而,在C++中,bool
类型被保证只能是true
或false
(分别隐式地转换为1
和0
),因此从这个角度看,这不是一个很大的问题,但人们不习惯在代码中看到这样的事情,这为不这样做提供了一个很好的理由。只要说b = b && x
就可以了。
发布于 2008-08-28 21:15:20
主要有两个原因。简而言之,仔细考虑;这可能有一个很好的理由,但如果你的评论中有非常明确的原因,因为它可能是脆弱的,正如你自己所说,人们通常不习惯看到这样的代码。
按位异或!=逻辑异或(0和1除外)
首先,如果您操作的值不是false
和true
(或整数形式的0
和1
),则^
运算符可能引入与逻辑xor不等价的行为。例如:
int one = 1;
int two = 2;
// bitwise xor
if (one ^ two)
{
// executes because expression = 3 and any non-zero integer evaluates to true
}
// logical xor; more correctly would be coded as
// if (bool(one) != bool(two))
// but spelled out to be explicit in the context of the problem
if ((one && !two) || (!one && two))
{
// does not execute b/c expression = ((true && false) || (false && true))
// which evaluates to false
}
感谢user @Patrick最先表达了这一点。
操作顺序
其次,作为位运算符的|
、&
和^
不会短路。此外,在一条语句中链接在一起的多个位运算符--甚至使用显式括号--可以通过优化编译器重新排序,因为所有3个操作通常都是可交换的。如果操作的顺序很重要,这一点很重要。
换句话说
bool result = true;
result = result && a() && b();
// will not call a() if result false, will not call b() if result or a() false
并不总是给出相同的结果(或结束状态)
bool result = true;
result &= (a() & b());
// a() and b() both will be called, but not necessarily in that order in an
// optimizing compiler
这一点特别重要,因为您可能无法控制方法a()
和b()
,或者其他人可能会在不了解依赖关系的情况下随后更改它们,并导致严重的(通常仅限于发布-构建)错误。
发布于 2008-08-28 17:56:49
我认为
a != b
就是你想要的
https://stackoverflow.com/questions/24542
复制相似问题