Why doesn't the bitwise & operator short-circuit?
Asked Answered
M

6

8

We all know that the logical && operator short circuits if the left operand is false, because we know that if one operand is false, then the result is also false.

Why doesn't the bitwise & operator also short-circuit? If the left operand is 0, then we know that the result is also 0. Every language I've tested this in (C, Javascript, C#) evaluates both operands instead of stopping after the first.

Is there any reason why it would be a bad idea the let the & operator short-circuit? If not, why don't most languages make it short-cicuit? It seems like an obvious optimization.

Mortification answered 13/3, 2012 at 16:46 Comment(3)
One reason would be to allow for side effects of function calls.Weswesa
Since bitwise operators are usually used for, well, bitwise operations on integer operands (and those usually correspond to single machine instructions) it would be anything else than an optimization to introduce an additional conditional for checking the rare 0 cases. Why does multiplication not short-circuit on 0? Well, because it's a simple arithmetic operation corresponding to a single machine instruction and checking nobody would ever check every multiplication for a 0 operand.Monocotyledon
The bitwise | operator could short circuit if the left operand was 0xFFFFFFFF.Mortification
J
11

I'd guess it's because a bitwise and in the source language typically gets translated fairly directly to a bitwise and instruction to be executed by the processor. That, in turn, is implemented as a group of the proper number of and gates in the hardware.

I don't see this as optimizing much of anything in most cases. Evaluating the second operand will normally cost less than testing to see whether you should evaluate it.

Javier answered 13/3, 2012 at 16:52 Comment(2)
It would benefit if the second operand involved an expensive computation.Mortification
@PeterOlson Yes, and only in the rare case the left operand is 0. Remember that we're talking about integers here and an integer value of 0 is much rarer than a boolean value of false (even if maybe more frequent than other numbers).Monocotyledon
I
8

Short-circuiting is not an optimization device. It is a control flow device. If you fail to short-circuit p != NULL && *p != 0, you will not get a marginally slower program, you will get a crashing program.

This kind of short-circuiting almost never makes sense for bitwise operators, and is more expensive than normal non-short-circuiting operator.

Isidora answered 13/3, 2012 at 17:2 Comment(2)
This argument seems backwards to me. Short-circuiting can be used as a flow control device because it exists as an optimization. If && didn't short-circuit, code like this would never have been valid to write; it would have to be two separate tests. However, I agree that bitwise short-circuiting would be sufficiently rare in practice that it would probably more expensive in the long run. It all depends on the likelihood of a 0 value for the left operand in the context of the calling code.Sweepstakes
@QuinnTaylor Optimisation, by definition, affects only performance, and not meaning. Such code gets writren because it is natural to write code like this, and alternatives are awkward. If && didn't short-circuit, then the language would probably die off and be replaced by something that is not awkward to use.Isidora
D
2

Bitwise operations are usually so cheap that the check would make the operation twice as long or more, whereas the gain from short-circuiting a logical operator is potentially very great.

Discuss answered 13/3, 2012 at 16:53 Comment(0)
S
2

If the compiler has to emit a check for both operands of & I guess that you it'll be much slower in any NORMAL condition.

Somite answered 13/3, 2012 at 16:53 Comment(0)
H
2

For the same reason that * does not short-circuit if the first operand is 0 -- it would be an obscure special case and adding special runtime tests for it would make all multiplies slower.

When the operands are not constants, short circuiting is more expensive than not short circuiting, so you don't want to do it unless the programmer explicitly requests it. So you really want to have clean and simple rules as to when it occurs.

Hearne answered 13/3, 2012 at 18:8 Comment(1)
That is not at all obvious. 64 bit Intel HW instructions may implement checks for zeroes internally. That is why you do not check.Waves
A
0

The boolean short-circuit is a convenience for the programmer, because this is what they usually want. If it didn't exist, some expressions - such as p != NULL && *p != 0 would be harder to type (but still possible).

On the other hand, bitwise operators assume lower level of programming and do exactly what is typed. Working without short-circuit in this scenario is more likely.

If bitwise operators did short-circuit too, dealing with that case when this behavior is unwanted would be that much more cumbersome. If I had an expression doA() & doB() where both calls must execute in all cases, I would suddenly have to split it into few complete statements. Not to mention how hard it would be to spot these unlikely bugs.

Arvie answered 13/6 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.