a[8] is an array of booleans. I am trying to calculate a boolean expression looking like the following.
bool a[8];
.....
bool result=a[0]*(a[3]+a[6]*(a[4]+a[7]*a[5]))+a[1]*(a[6]*a[3]+a[4]+a[7]*a[5])+a[2]*(a[5]+a[7]*(a[4]+a[6]*a[3]));
The expression is long, but conceptually nothing complicated. The only bug is, it seems the result is different when I replace the * in the expression with && (in both cases I am expecting a logical AND) or replace + with || (expecting logical OR).
I am not sure which ones would be correct, the boolean operators or the mathematical notations of multiplication, addition etc. Worse, none give any error, i.e. the compiler is happy with both. Which one is safer and correct?
They are almost the same for bool
operands. But there are subtle differences:
*
and +
will widen the bool
type arguments to int
types.
The type of the expression a || b
is bool
, whereas a + b
is int
. Ditto for &&
and *
.
*
and +
are not sequencing points, whereas &&
and ||
are.
*
and +
are not short-circuited, whereas &&
and ||
are.
They occupy very different positions in the operator precedence table. So substitution is not straightforward.
If a
is a bool
, and b
is also a bool
but is not initialised then the behaviour of a || b
is defined, but a + b
is undefined since a bool
can contain a trap representation in C++. Similar expressions can be conjured for &&
and *
.
A very long chain of a + b + c + ...
could overflow the int
type, the behaviour of which is undefined.
(3) means that a++ * a++
is undefined behaviour but a++ || a++
is not.
(Not really relevant here but worth noting: note that &&
and ||
lose their short circuiting property if they are overloaded).