5

I was just wondering if there is an XOR logical operator in C (something like && for AND but for XOR). I know I can split an XOR into ANDs, NOTs and ORs but a simple XOR would be much better. Then it occurred to me that if I use the normal XOR bitwise operator between two conditions, it might just work. And for my tests it did.

Consider:

int i = 3;
int j = 7;
int k = 8;

Just for the sake of this rather stupid example, if I need k to be either greater than i or greater than j but not both, XOR would be quite handy.

if ((k > i) XOR (k > j))
   printf("Valid");
else
   printf("Invalid");

or

printf("%s",((k > i) XOR (k > j)) ? "Valid" : "Invalid");

I put the bitwise XOR ^ and it produced "Invalid". Putting the results of the two comparisons in two integers resulted in the 2 integers to contain a 1, hence the XOR produced a false. I've then tried it with the & and | bitwise operators and both gave the expected results. All this makes sense knowing that true conditions have a non zero value, whilst false conditions have zero values.

I was wondering, is there a reason to use the logical && and || when the bitwise operators &, | and ^ work just the same?

Magisch
  • 7,312
  • 9
  • 36
  • 52
reubensammut
  • 182
  • 1
  • 1
  • 12
  • Possible duplicate of [Logical XOR operator in C++?](http://stackoverflow.com/questions/1596668/logical-xor-operator-in-c) – phuclv Apr 12 '16 at 16:51

5 Answers5

13

You don't need logical XOR, I have forgotten the SO question, but it's similar to what you're thinking, basically we don't need XOR, it's equivalent to != anyway

FALSE XOR FALSE == FALSE
FALSE XOR TRUE == TRUE
TRUE XOR FALSE == TRUE
TRUE XOR TRUE == FALSE


FALSE != FALSE == FALSE
FALSE != TRUE == TRUE
TRUE != FALSE == TRUE
TRUE != TRUE == FALSE

I'll search my favorites, and paste here the link later...

Michael Buen
  • 38,643
  • 9
  • 94
  • 118
  • 2
    `&`, `|`, and `^` might work the same as `||` and `&&` when used on *boolean* values, but normally you don't use `&`, `|`, and `^` on booleans -- you use them to work with bits (hence why they're *bitwise* operators). When used appropriately, the bitwise operators aren't the same as the logical operators. – mipadi May 05 '10 at 13:49
  • historically, bitwise operators and logical operators share a common token (i.e. `&` and `|`), there's no `&&` and `||` yet http://stackoverflow.com/questions/3930042/equivalent-of-visual-basics-and-and-or-in-c/3930123#3930123 Check the Neonatal C: http://cm.bell-labs.com/cm/cs/who/dmr/chist.html And it is unfortunate that they retain the old operator precedence of `&` and `|` when they added `&&` and `||` to C. hence this unfortunate parenthesisation(sic) on masking idiom: `if ( (input & alt) == alt )`. Otherwise, it could be more concise: `if ( input & alt == alt )` – Michael Buen Jan 01 '11 at 04:01
  • That's not true. != isn't a logical xor. See: `2 LOGICAL_XOR 4` gives `false` (which is true), but `2 != 4` yields `true` (which is incorrect). The right answer is below ([Joe D answer](http://stackoverflow.com/questions/2773186/what-is-the-point-of-the-logical-operators-in-c/2938554#2938554) ) – Yury Oct 26 '11 at 08:01
  • 1
    Since the asker asked about logical operator, both numbers needed be properly reduced to booleans first before applying whatever operator/macro to both booleans. Just apply double nots on each side of the expression. !!2 != !!4 yields false. i.e. true != true yields false – Michael Buen Oct 26 '11 at 11:55
  • !! is the most idiomatic way to reduce the number to a boolean. If there's any other technique, I would be more than glad to know :-) – Michael Buen Oct 26 '11 at 11:57
11

The bitwise operators do not work "just the same" as the && and || operator. For a start, && and || perform short-circuited evaluation, whereas the the bitwise operators do not. In other words, you can't do something like this with the bitwise operators:

int * p = 0;
(p != 0) && (*p = 1);

because if you said:

(p != 0) & (*p = 1);

both subexpressions would be evaluated, and you would dereference the null pointer.

  • Internally no, but I still got the same results – reubensammut May 05 '10 at 12:43
  • 12
    @reubensammut: You will not get the same results if you depend on the short-circuitedness. `if(returnsTrue() || explodesWorld())` will not destroy the world, whereas `if(returnsTrue() | explodesWorld())` will. – unwind May 05 '10 at 12:45
1

Bitwise XOR does not work as would a logical XOR when its operands are integer values:

2^4 ? "Valid" : "Invalid"

gives "Valid" but should give "Invalid"

mouviciel
  • 66,855
  • 13
  • 106
  • 140
1

In C arguments of logical operators are treated as Boolean values - anything zero is treated as "false", and anything else (yes, negative values too) are "true". Bitwise ops work on individual bits, and as Neil already noted, are not subject to short-circuit evaluation as logical ops are.

In your example the results are totally valid and expected since bit-wise xor between two ones is zero.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
1

If you want a logical xor operator in C, then you can use this:

#define xor != 0 ^ !!

It works by converting both sides of the expression to booleans and xoring them. You can use it as if you were using && or ||, like this:

if (a xor b)

AFAICT, there aren't any problems with it.

Joe D
  • 2,855
  • 2
  • 31
  • 25