Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!uhccux!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.c Subject: Re: C history question Keywords: C design, XOR Message-ID: <2080@munnari.oz.au> Date: 11 Sep 89 11:10:39 GMT References: <575@calmasd.Prime.COM> Sender: news@cs.mu.oz.au Lines: 52 In article <575@calmasd.Prime.COM>, wlp@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.