Is there a "very bad thing" that can happen &&=
and ||=
were used as syntactic sugar for bool foo = foo && bar
All the operators +=
, -=
, *=
, /=
, &=
, |=
... are arithmetic and provide same expectation:
x &= foo() // We expect foo() be called whatever the value of x
However, operators &&=
and ||=
would be logical, and these operators might be error-prone because many developers would expect foo()
be always called in 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
Do we really need to make C/C++ even more complex to get a shortcut for x = x && foo()
?
Do we really want to obfuscate more the cryptic statement x = x && foo()
?
Or do we want to write meaningful code like if (x) x = foo();
?
&&=
If &&=
operator was available, then this code:
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
is equivalent to:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
This first code is error-prone because many developers would think f2()
is always called whatever the f1()
returned value. It is like writing bool ok = f1() && f2();
where f2()
is called only when f1()
returns true
.
f2()
to be called only when f1()
returns true
, therefore the second code above is less error-prone.f2()
to be always called), &=
is sufficient:&=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
Moreover, it is easier for compiler to optimize this above code than that below one:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
&&
and &
We may wonder whether the operators &&
and &
give the same result when applied on bool
values?
Let's check using the following C++ code:
#include
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);
}
Output:
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
======================
Therefore YES we can replace &&
by &
for bool
values ;-)
So better use &=
instead of &&=
.
We can consider &&=
as useless for booleans.
||=
operator
|=
is also less error-prone than||=
If a developer wants f2()
be called only when f1()
returns false
, instead of:
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 ...
I advice the following more understandable alternative:
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)
or if you prefer all in one line style:
// 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();