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