Kac*_*che 115 c++ boolean-operations
有没有"非常糟糕的事情"可以发生&& =和|| =被用作语法糖bool foo = foo && bar和bool foo = foo || bar?
Kon*_*lph 69
A bool可能只是true或false在C++中.因此,使用&=和|=相对安全(即使我不特别喜欢这种表示法).确实,它们将执行位操作而不是逻辑操作(因此它们不会短路)但这些位操作遵循明确定义的映射,这实际上等同于逻辑操作,只要两个操作数都是类型的bool.1
与其他人在这里所说的相反bool,C++必须永远不会有不同的价值,例如2.将该值分配给a时bool,它将true按照标准进行转换.
将无效值转换为a的唯一方法bool是使用reinterpret_caston指针:
int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn’t on my PC!)
Run Code Online (Sandbox Code Playgroud)
但是,由于此代码无论如何都会导致未定义的行为,因此我们可以安全地忽略这个符合C++代码的潜在问题.
1无可否认,这是一个相当大的警告,因为Angew的评论说明:
bool b = true;
b &= 2; // yields `false`.
Run Code Online (Sandbox Code Playgroud)
原因是b & 2执行整数提升,使得表达式等效static_cast<int>(b) & 2,然后导致0,然后将其转换回a bool.因此,确实存在operator &&=可以提高类型安全性.
Nik*_*iki 44
&&并且&具有不同的语义:&&如果第一个操作数是,则不会计算第二个操作数false.即类似的东西
flag = (ptr != NULL) && (ptr->member > 3);
Run Code Online (Sandbox Code Playgroud)
是安全的,但是
flag = (ptr != NULL) & (ptr->member > 3);
Run Code Online (Sandbox Code Playgroud)
不是,虽然两个操作数都是类型bool.
同样是真实的&=和|=:
flag = CheckFileExists();
flag = flag && CheckFileReadable();
flag = flag && CheckFileContents();
Run Code Online (Sandbox Code Playgroud)
将表现得与以下不同:
flag = CheckFileExists();
flag &= CheckFileReadable();
flag &= CheckFileContents();
Run Code Online (Sandbox Code Playgroud)
oli*_*bre 26
所有的运营商+=,-=,*=, /=,&=,|=...是算术,并提供同样的期望:
x &= foo() // We expect foo() be called whatever the value of x
Run Code Online (Sandbox Code Playgroud)
但是,运算符&&=并且||=是合乎逻辑的,并且这些运算符可能容易出错,因为许多开发人员会期望foo()总是被调用x &&= foo().
bool x;
// ...
x &&= foo(); // Many developers might be confused
x = x && foo(); // Still confusing but correct
x = x ? foo() : x; // Understandable
x = x ? foo() : false; // Understandable
if (x) x = foo(); // Obvious
Run Code Online (Sandbox Code Playgroud)
我们真的需要让C/C++更复杂才能获得快捷方式x = x && foo()吗?
我们真的想要更多地模糊这些神秘的陈述x = x && foo()吗?
或者我们是否想要编写有意义的代码if (x) x = foo();?
&&=如果&&=运算符可用,则此代码:
bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value
Run Code Online (Sandbox Code Playgroud)
相当于:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
Run Code Online (Sandbox Code Playgroud)
第一个代码容易出错,因为许多开发人员会认为f2()总是调用f1()返回值.这就像写作只在返回时调用的bool ok = f1() && f2();地方.f2()f1()true
f2()在f1()返回时调用true,那么上面的第二个代码不容易出错.f2()始终被调用),&=就足够了:&=bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Run Code Online (Sandbox Code Playgroud)
此外,编译器更容易优化上面的代码而不是下面的代码:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
Run Code Online (Sandbox Code Playgroud)
&&和&我们可能不知道经营者是否&&和&何时施加给出相同的结果bool值?
我们使用以下C++代码进行检查:
#include <iostream>
void test (int testnumber, bool a, bool b)
{
std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
"a && b = "<< (a && b) <<"\n"
"a & b = "<< (a & b) <<"\n"
"======================" "\n";
}
int main ()
{
test (1, true, true);
test (2, true, false);
test (3, false, false);
test (4, false, true);
}
Run Code Online (Sandbox Code Playgroud)
输出:
1) a=1 and b=1
a && b = 1
a & b = 1
======================
2) a=1 and b=0
a && b = 0
a & b = 0
======================
3) a=0 and b=0
a && b = 0
a & b = 0
======================
4) a=0 and b=1
a && b = 0
a & b = 0
======================
Run Code Online (Sandbox Code Playgroud)
因此是我们可以更换&&用&的bool值;-)
所以最好使用&=代替&&=.
我们可以认为&&=布尔无用.
||=操作者
|=也不太容易出错比||=
如果开发人员只想f2()在f1()返回时调用false,而不是:
bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...
Run Code Online (Sandbox Code Playgroud)
我建议以下更容易理解的替代方案:
bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)
Run Code Online (Sandbox Code Playgroud)
或者如果你喜欢所有的一线风格:
// this comment is required to explain to developers that
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();
Run Code Online (Sandbox Code Playgroud)