I'm learning c++ and I've run into some behaviour that I can't explain. The two pieces of code below provide different results, while I would expect them to be equivalent:
success = true;
vector<instruction>::const_iterator i;
for (i = instructions.begin(); i != instructions.end(); ++i) {
bool up = update(*i);
success = success && up;
}
and
success = true;
vector<instruction>::const_iterator i;
for (i = instructions.begin(); i != instructions.end(); ++i) {
success = success && update(*i);
}
I have the impression that the second version always takes the initial value of the iterator. Could someone explain me the reason?
The two pieces of code are not equivalent.
The first one always calls update
, while the second one will not. The reason is that &&
does something called short-circuit boolean evaluation
. If success
is false, the second half of the expression is not evaluated.
Note that you did not post what update
is or what is returned. Therefore we can only assume what may be able to be returned from update
, which is either going to be true
or false
.
If you wanted update
to always be called, it should be placed first in the &&
expression.
The operator &&
will not evaluate the right hand side if the result is computable with just the left hand side value. We call this short-circuiting.
Once success
is false
, update(*i)
will no longer be called.
Aside from your first block of code (which always calls update(*i)
), one fix is to use the operator &
instead which always evaluates both arguments. Another fix is to write
success = update(*i) && success;
But that's vulnerable to recalcitrant refactoring. Better still, use
success &= update(*i);
But be aware of this comment by @Angew:
Using &=
in a boolean context is dangerous. What if update
now (or after a future refactoring) returns an int
with the semantics "non-zero for true" (cf. isdigit
and friends)? Remember that bool(true & 2)
is false
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With