C history question
Richard O'Keefe
ok at cs.mu.oz.au
Mon Sep 11 21:10:39 AEST 1989
In article <575 at calmasd.Prime.COM>, wlp at calmasd.Prime.COM (Walter Peterson) writes:
> C has bitwise operators for AND (&), OR (|) and XOR (^) and boolean
> operator for AND (&&) and OR (||), but not for XOR (^^). Why?
No, && is *not* a "boolean" operator, it is a "SHORT-CIRCUIT" operator.
&& and || are in fact dispensible:
(a) && (b) has the same effect as (a) ? !!(b) : 0
(a) || (b) has the same effect as (a) ? 1 : !!(b)
On a surprising number of machines, short-circuit operators are
_slower_ than boolean operators for simple expressions, typically because
conditional branches do nasty things to pipelines. If you want
and(x,y) = 1 if x != 0 and y != 0, 0 otherwise
or(x,y) = 1 if x != 0 or y != 0, 0 otherwise
xor(x,y) = (x != 0) != (y != 0)
just
#define and(x,y) (!!(x) & !!(y))
#define or( x,y) (!!(x) | !!(y))
#define xor(x,y) (!!(x) ^ !!(y))
or for an even prettier hack
#define xor(x,y) (!(x) != !(y))
> What happened to the boolean XOR operator?
Nothing happened to it. C inherited short-circuiting operators from
B, which copied the idea from BCPL.
> If && makes sense for the
> boolean AND and || makes sense for the boolean OR, why doesn't ^^ make
> sense for the boolean XOR ?
Because && is not boolean AND but short-circuiting and.
The point of (a) && (b) is to skip evaluating (b) when (a) is false;
that lets you do things like (i >= 0 && a[i] != x) safely.
But in exclusive or, what can you skip?
> Most assemblers that I know have XOR as a single instruction so why
> make people go to the trouble of writing something like
> (a || b) && (!(a && b)) when a ^^ b is so much "cleaner".
Most computers have an AND or AND-NOT instruction. But && doesn't
generate that instruction, it generates branches. AND comes from
the & operator. Most computers have an OR instruction. But || doesn't
generate that instruction, it generates branches. OR comes from
the | operator. In just the same way, if you way to generate an
XOR instruction, use ^. [A really good compiler might well notice that
an expression involving && or || is simple and generate an instruction
sequence using AND or OR.]
Nobody has to write (a || b) && !(a && b). As I said above, just
#define xor(x,y) (!(x) != !(y))
and then write
xor(a,b)
which is IMHO rather clearer than a^^b.
More information about the Comp.lang.c
mailing list