Topic: Logical XOR
Author: jackklein@spamcop.net (Jack Klein)
Date: Thu, 15 Apr 2004 04:17:37 +0000 (UTC) Raw View
On Wed, 14 Apr 2004 16:49:28 +0000 (UTC), kprateek88@yahoo.com
(Prateek R Karandikar) wrote in comp.std.c++:
> Why isn't there a logical XOR operator ^^, at least for the sake of
> completeness? If a redundant unary + can be provided "for the sake of
> symmetery and
> completeness", then why not ^^ ?
This question has been asked many times, in both C and C++ newsgroups.
Such an operator might look similar to the && and || operators, but
would in fact be quite different. It could not exhibit the short
circuit evaluation feature required of the existing logical operators.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 15 Apr 2004 05:02:49 +0000 (UTC) Raw View
Prateek R Karandikar wrote:
> Why isn't there a logical XOR operator ^^, at least for the sake of
> completeness? If a redundant unary + can be provided "for the sake of
> symmetery and completeness", then why not ^^ ?
Hey, it's time for the Logical XOR thread again!
Logical AND and OR have short-circuit semantics,
but that's meaningless for XOR. If you truly need
a logical XOR, write (a ^^ b) as (!(a) != !(b)),
or as (!(a) ^ !(b)).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: nobody@nowhere.invalid (Jack Applin)
Date: Thu, 15 Apr 2004 05:09:14 +0000 (UTC) Raw View
My xor FAQ follows.
Jack Applin
------------------------------------------------------------------------
People often ask why there isn't a logical exclusive-or (xor) operator.
After all, the && and || operators exist, so perhaps ^^ should, too.
What would ^^ do? Presumably, it would be as similar as possible
to && and ||, so we should study their attributes:
1) Left-to-right evaluation
f() && g() calls f() before g()
2) Short-circuit evaluation
f() && g() doesn't call g() if f() is false.
3) Sequence point
*p++ && *p++ is well-defined
4) Treating the arguments as boolean values
(1 && 2)==1, whereas (1 & 2)==0.
(3 && "hello")==1, whereas (3 & "hello") is a syntax error
5) A boolean result
(5 && 6)==1, whereas (5 & 6)==4.
In C++, the operands and result of && and || are bool, not int,
but the essence is the same.
6) Both arguments should only have to be written once
Expressions such as (a ? !b : b) require that expression b occur twice,
which is unwieldy for a complex b, unless an evil macro is used.
The nature of xor precludes (2), but the others are possible.
Proposed code L-to-R? seq. point? bool args? bool result? args once?
-------------- ------- ----------- ---------- ------------ ----------
a ^ b no no no no yes
a != b no no no yes yes
(!a)!=(!b) no no yes yes yes
xor_func(a,b) no no yes yes yes
a ? !b : b yes yes yes no no
a ? !b : !!b yes yes yes yes no
The fact that you can achieve the same effect doesn't end the discussion.
A ^^ operator might be useful for clarity and brevity.
"I've never needed a ^^ operator." It's hard to say--our tools guide our
thinking. Nobody uses ^^ now, because it's not available. If it were
available, perhaps it would get used.
Does anybody have any quotes from Bjarne Stroustrup on this?
Dennis Ritchie said:
> There are both historical and practical reasons why there is no ^^
> operator. The practical is: there's not much use for the operator.
> The main point of && and || is to take advantage of their
> short-circuit evaluation not only for efficiency reasons, but more
> often for expressiveness and correctness. For example, in
>
> if (cond1() && cond2()) ...
>
> it is often important that cond1() is done first, because if it's false
> cond2() may not be well defined, or because cond1() is cheap and
> cond2() is expensive. Syntax to handle the situation has made it into
> lots of languages; compare Ada's "and then'. By contrast, an ^^
> operator would always force evaluation of both arms of the expression,
> so there's no efficiency gain. Furthermore, situations in which ^^ is
> really called for are pretty rare, though examples can be created.
> These situations get rarer and stranger as you stack up the operator--
>
> if (cond1() ^^ cond2() ^^ cond3() ^^ ...) ...
>
> does the consequent exactly when an odd number of the condx()s
> are true. By contrast, the && and || analogs remain fairly plausible
> and useful.
>
> Historical: C's predecessors (B and BCPL) had only the bitwise
> versions of | & ^. They also had a special rule, namely that in an
> statement like
>
> if (a & b) ...
>
> the '&", being at the 'top level' of the expression occurring in
> `truth-value context' (inside the if()) was interpreted just
> like C's &&. Similarly for |. But not so for ^.
>
> One of the early bits of C evolution was the creation of separate
> && and || operators. This was better than the special rule, which was
> hard to explain.
>
> In other words, the whole question arises because of the particular
> method of symmetry-breaking that C chose. Suppose I had reacted to
> the situation of BCPL and B taking their notion of
>
> if (a & b) ...
>
> and had people say
>
> if (a) andif (b) ...
>
> (and similarly with "orif") One can make a case that this kind of
> syntax is better than && and ||, If it had happened,
> would people be asking for "xorif"? Probably not.
>
> My guess is that &, &&; |,||; ^,^^ is a false symmetry. But it's
> one that people seem to want, and, though it's not much help,
> adding it wouldn't do much harm.
>
> Dennis
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Thu, 15 Apr 2004 15:15:08 +0000 (UTC) Raw View
Jack Applin wrote:
> My xor FAQ follows.
Maybe time for an update of your FAQ? Consider:
#include <iostream>
using namespace std;
struct X
{
operator bool() const { return true; }
X operator!() const { return X(); }
};
int main()
{
X a, b;
cout << ( a ? !b : !!b ) << endl; // Oops...
}
Thus your list is not correct. Besides that, there is one more=20
properties that one should take into account: ICEs. By ICEs I refer to=20
the fact that when both 'a' and 'b' are integral constant expressions=20
(ICEs for short), the result is also an ICE. Here's a corrected table=20
with some more proposals how to write XOR:
ltr =3D left-to-right evaluation
sqp =3D sequence point
args =3D arguments guaranteed to be converted to bool
res =3D boolean result guaranteed
ICE =3D integral constant expressions
b1 =3D single occurence of 'b'
Proposed code ltr? sqp? args res? ICE? b1?
------------- ---- ---- ---- ---- ---- ----
a ^ b no no no no yes yes
a !=3D b no no no no yes yes
(!a)!=3D(!b) no no no no yes yes
my_xor_func(a,b) no no yes yes no yes
a ? !b : b yes yes no no yes no
a ? !b : !!b yes yes no no yes no
[* see below] yes yes yes yes yes no
(( a bool_xor b )) yes yes yes yes yes yes
[* =3D a ? !static_cast<bool>(b) : static_cast<bool>(b)]
But what is this funny "(( a bool_xor b ))"? Well, you can create some
macros that allow you such a strange syntax. Note that the
double-brackets are part of the syntax and cannot be removed! The set of
three macros (plus two internal helper macros) also provides bool_and
and bool_or. That given, what is it good for? We have && and || already,
why do we need such a stupid syntax? Well, && and || can't guarantee
that the arguments are converted to bool and that you get a bool result.=20
Think "operator overloads", like shown in the example above.
Finally, here's how the macros look like:
#define BOOL_DETAIL_AND_HELPER(x) \
static_cast<bool>(x):false
#define BOOL_DETAIL_XOR_HELPER(x) \
!static_cast<bool>(x):static_cast<bool>(x)
#define bool_and )?BOOL_DETAIL_AND_HELPER(
#define bool_or )?true:static_cast<bool>(
#define bool_xor )?BOOL_DETAIL_XOR_HELPER(
Have fun...
Daniel
PS: Note that I never claimed you really want to use that stuff ;)
--=20
Daniel Frey
aixigo AG - financial solutions & technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Wed, 14 Apr 2004 16:49:28 +0000 (UTC) Raw View
Why isn't there a logical XOR operator ^^, at least for the sake of
completeness? If a redundant unary + can be provided "for the sake of
symmetery and
completeness", then why not ^^ ?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]