Why isn't there a logical XOR operator?

  • Thread starter Christopher Benson-Manica
  • Start date
M

Martin Dickopp

Christian Bau said:
You say that logical xor is used much more rarely than logical and/or.
Question: Has anybody _ever_ found a situation where they would have
wanted a logical xor?

Yes. I often use the bits of an `unsigned int' struct member to
represent a number of two-state attributes of an object, and
to test for (a combination of) attributes, I use the idiom

if (x->flags & FLAG_FOO) ...
if ((x->flags & FLAG_BAR) || (y->flags & FLAG_BAZ)) ...

where the tokens starting with FLAG_ are macros that expand to an
unsigned int constant expression with one and only one bit that is
set to 1. For symmetry reasons, I would prefer it if I could also
write

if ((x->flags & FLAG_BLAH) ^^ (y->flags & FLAG_BLUBB)) ...

IMHO, that would look nicer (i.e., more like similar expressions
involving && or ||) than the alternatives.

Martin
 
C

Christian Bau

Martin Dickopp said:
Yes. I often use the bits of an `unsigned int' struct member to
represent a number of two-state attributes of an object, and
to test for (a combination of) attributes, I use the idiom

if (x->flags & FLAG_FOO) ...
if ((x->flags & FLAG_BAR) || (y->flags & FLAG_BAZ)) ...

where the tokens starting with FLAG_ are macros that expand to an
unsigned int constant expression with one and only one bit that is
set to 1. For symmetry reasons, I would prefer it if I could also
write

if ((x->flags & FLAG_BLAH) ^^ (y->flags & FLAG_BLUBB)) ...

IMHO, that would look nicer (i.e., more like similar expressions
involving && or ||) than the alternatives.

Yes, but have you actually needed it? In a real life program? Has it
happened that you wanted to take some action if exactly one of the flags
was set, but not both?

(A relatively common case would be where you believe that two conditions
that look different should have the same truth values and you use an
assert to either confirm this or find errors in the program or your
understanding of the program. But in this case I would prefer == or !=
because they express this clearer. For example, you might have two
pointers src and dst, and you know that if one is not NULL then the
other is not NULL as well, so you might write assert ((src != NULL) ==
(dst != NULL)) .)
 
P

pete

Christian said:
You say that logical xor is used much more rarely than logical and/or.
Question: Has anybody _ever_ found a situation where they would have
wanted a logical xor?

(!(a) != !(b)) is adequate for the situation.

unsigned char bit_rev(unsigned char byte)
{
unsigned hi_mask, lo_mask;

hi_mask = ((unsigned char)-1 >> 1) + 1;
lo_mask = 1;
do {
if (!(byte & hi_mask) != !(byte & lo_mask)) {
byte ^= hi_mask | lo_mask;
}
hi_mask >>= 1;
lo_mask <<= 1;
} while (hi_mask > lo_mask);
return byte;
}
 
M

Martin Dickopp

Christian Bau said:
Yes, but have you actually needed it?

Yes. (Well, "needed" is too strong, but I would have liked to have it.)
In a real life program?

Not in a program I have been paid to write. In fact, not in a program
I have published yet. But in a program that is supposed to be applied to
a real life problem - it's not some kind of contrived example program.
Has it happened that you wanted to take some action if exactly one of
the flags was set, but not both?

One flag describes whether an object is "active" in some sense (for
example, a GUI element which can be "selected" or "unselected"). The
other flag describes what the former flag should be set to. If and only
if the former flag will change, i.e. the object is inactive and will be
activated or it is active and will be deactivated, some actions are to
be performed (e.g., a GUI element will be redrawn).

Martin
 
S

stelios xanthakis

Arthur J. O'Dwyer said:
Of course, both cases are pretty ugly, here. But I haven't yet
come up with a good example. ;-)
And while I think it would have been cool if C had been designed
with a ^^ operator from the start, IMHO it's much too late now to
try adding it to the standard language. C doesn't need any more
syntax, and even if it did, I don't think the new syntax would find
many willing users. A new version of C would IMHO suffer the same
problems as C99 still suffers w.r.t. market share, only worse.
Now, a *new* language... :)

This is what I do when I need xor:

static inline int xor (int a, int b)
{
return a ? !b : b;
}

OR implement this with the binary '^' operator (I think it's slower
if you optimize).

The thing is that we couldn't do this with || and &&, because
these have early termination. And that's probably the reason for
their existance. In xor both must be evaluated.

And another problem is multiple xors. What happens then??

a ^^ b ^^ c ????

So xor is rather special


Stelios
 
J

Jeremy Yallop

stelios said:
And another problem is multiple xors. What happens then??

a ^^ b ^^ c ????

So xor is rather special

No more than (e.g.) == or < in this respect as far as I can see.

Jeremy.
 
T

Tom St Denis

Jeremy Yallop said:
No more than (e.g.) == or < in this respect as far as I can see.

== is a short circuit though. The intention would be that ^^ would be a
short-circuit (otherwise I don't see the point) and as the others pointed
out you have to evaluate both sides to determine the result (therefore it
cannot short circuit).

What you could do is make ^& and ^| for NAND and NOR (former shorts if left
is zero, latter if left is one) and you'd have all four short-circuits ;-)

Well actually make ^& into ^^ since it's ambiguous with ^&varname, etc...so
you get

^^ = NAND
^| = NOR
|| = OR
&& = AND

Tom
 
M

Martin Dickopp

And another problem is multiple xors. What happens then??

a ^^ b ^^ c ????

I guess it would have left-to-right associativity just like &&
and ||, i.e. behave like (a ^^ b) ^^ c. But even if it behaved
like a ^^ (b ^^ c), the result would be the same. Where do you
see a problem?

Martin
 
T

Tom St Denis

Martin Dickopp said:
I guess it would have left-to-right associativity just like &&
and ||, i.e. behave like (a ^^ b) ^^ c. But even if it behaved
like a ^^ (b ^^ c), the result would be the same. Where do you
see a problem?

You cannot short circuit the XOR logical op. So what's the point?

Tom
 
R

Richard Bos

Tom St Denis said:
== is a short circuit though.

No, it's not.

a == b

needs to evaluate both a and b, and

a == b == c

needs to evaluate all three.

Richard
 
D

Dan Pop

In said:
However, (!a != !b) reflects the intent of the code,
which is the logical relationship between a and b, better.

Not being the OP, I can't figure out the intent of his code.

Dan
 
D

Dan Pop

In said:
Finding an XOR in code would be rather annoying (to track down the
header file where it's defined), I would think.

Why bother, the semantics should be obvious!

Finding definitions in headers is a piece of cake to anyone with the
right tools. People that maintain software they haven't written have to
do this all the time.

Dan
 
T

Tom St Denis

Martin Dickopp said:
I already explained in <[email protected]> why I would
like to have a ^^ operator even without short-circuiting logic.

how is

if (a ^^ b) { ... }

any diff from

if (a ^ b) { .... }

Even in a stmt you could write

(a^b)?1:0

Tom
 
P

PlasmaDragon

You say that logical xor is used much more rarely than logical and/or.
Question: Has anybody _ever_ found a situation where they would have
wanted a logical xor?

Yes. It involved taking a string, consisting of astericks and spaces,
and making another string of asteriks and spaces, based on some rules.
I think it involved finite automata, or something like that. My
recollection is fuzzy.

And would the !a != !b thing be able to benefit from short circuiting?
If not, then there would be no harm in a logical xor, would there?
 
M

Martin Dickopp

Tom St Denis said:
how is

if (a ^^ b) { ... }

any diff from

if (a ^ b) { .... }

The assumed semantics of the ^^ operator is that it yields zero if both
operands have (possibly different) non-zero values.

Martin
 
T

Tom St Denis

Martin Dickopp said:
The assumed semantics of the ^^ operator is that it yields zero if both
operands have (possibly different) non-zero values.

Hmm? I don't get what that means. so

a^^a == 1?
a^^b == 0 if a != b?

or do you mean if a&b != 0 then a^^b == 0 ?

To me this just doesn't seem like a well thought out idea.

Tom
 
N

nrk

Tom said:
Hmm? I don't get what that means. so

a^^a == 1?

a ^^ a would always be expected to be 0.
a^^b == 0 if a != b?

Yes, but only if both a != 0 and b != 0 as well. If a == 10, b == 20, you
would still expect a ^^ b to be 0. That's why its called the "logical" xor
operator. However, the bitwise xor is not 0.
or do you mean if a&b != 0 then a^^b == 0 ?

Yep.

To me this just doesn't seem like a well thought out idea.

Nope. Its precisely how one would expect "logical" xor to function. This
is why there are several messages in this thread suggesting alternatives to
the logical xor such as:
!a != !b
!a ^ !b
!!a ^ !!b

You seem to have some mis-contrued notion of what a logical xor operator is
supposed to do. Consider it as something which maps both its operands to 1
if they are non-zero, 0 otherwise, and then performs a bitwise xor on them.

-nrk.
 
M

Martin Dickopp

Tom St Denis said:
Hmm? I don't get what that means. so

a^^a == 1?
No.

a^^b == 0 if a != b?
No.

or do you mean if a&b != 0 then a^^b == 0 ?
No.

To me this just doesn't seem like a well thought out idea.

Is "logical exclusive OR" really that hard to understand? The operator
would yield 1 if one and only one of its operands is 0, and it would
yield 0 otherwise.

Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top