The &&
and ||
operators use an early-exit strategy specifically to prevent the side-effects of the right-hand term.
This (slightly modified) C example from the Wikipedia page 280Z28 linked shows an example of where this is useful:
int denom = 0;
if (denom && num/denom) {
do_something();
}
In this case, early exit from evaluation of the terms means that the program will not throw a divide-by-zero error while evaluating the condition, which is A Good Thing.
Conversely the bit-wise operators are defined by the language specification to evaluate both terms, including all side effects, before performing the operation on them.
One way of thinking about this is to consider the bit-wise operators as eager and the logical operators as lazy with regard to their evaluations. Eager operators will evaluate all of their operands before continuing, lazy operators will consider the operands in sequence and exit early if possible.
Incidentally, the (hypothetical) ^^
operator cannot exit without evaluating both operands, since the result cannot be determined by a specific value of one operand as is the case with &&
and ||
.