Topic: Why no logical xor operator?
Author: harris.pc@googlemail.com
Date: Thu, 6 Sep 2012 13:05:20 CST
Raw View
On Friday, August 22, 2003 9:29:22 PM UTC+8, Daniel Frey wrote:
> OK, the table needs some corrections, as I showed that the guarantees
> given for bool args and bool results cannot be given by the proposed
> code. Also, there is another important property for such an idiom: If
> the arguments are integral constant expressions (ICEs), is the result
> also guaranteed to be an integral constant expression? Obviously, this
> is not given for a my_xor_func()-implementation. Another row should be
> added to reflect whether the 'b'-part is repeated in the user's code or
> not, as 'b' might be a long expression in practice, repeating it can be
> a maintenance nightmare. Note that I ask "Singular 'b'" to make "yes"
> the desirable answer. Here we go:
>
> Proposed code left-to-right? sequence point? bool args? bool
> result? ICE result? Singular 'b'?
> -------------- -------------- --------------- ----------
> ------------ ----------- -------------
> a ^ b no no no no
> yes yes
> a != b no no no no
> yes yes
> (!a)!=(!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
>
> [* = 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.
> Think "operator overloads". 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(
>
> Thanks to Paul Mensonides, Fernando Cacciola and John Torjo for feedback
> on the code on the boost list :)
>
> And please note that I never claimed someone could possibly need such
> stuff :o)
>
> Regards, Daniel
>
> --
> Daniel Frey
>
> aixigo AG - financial training, research and 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 ]
I had to make some changes for it to work on MSVC 2010 -- the brackets
weren't expanding correctly.
So it now looks like this:
#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_DETAIL_OPEN (
#define BOOL_DETAIL_CLOSE )
#define bool_and BOOL_DETAIL_CLOSE ? BOOL_DETAIL_AND_HELPER BOOL_DETAIL_OPE=
N
#define bool_or BOOL_DETAIL_CLOSE ? true:static_cast<bool> BOOL_DETAIL_OPEN
#define bool_xor BOOL_DETAIL_CLOSE ? BOOL_DETAIL_XOR_HELPER BOOL_DETAIL_OPE=
N
And works great :)
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: google@dalvander.com (Anders Dalvander)
Date: Tue, 19 Aug 2003 23:41:36 +0000 (UTC) Raw View
Why are there no logical-xor operator (^^) in the language? Though it
would not be able to use short-circuit evaluation, and the result
would be similar to the bitwise-xor operator (^). But if you put it
like that, there is really no need for logical-or nor logical-and
either as you could use bitwise-or and bitwise-and instead (except for
the short-circuit evaluation part).
Using:
operand-implicitly-converted-to-true = oict-true
operand-implicitly-converted-to-false = oict-false
oict-true ^^ oict-true == false
oict-false ^^ oict-true == true
oict-true ^^ oict-false == true
oict-false ^^ oict-false == false
1 ^^ 2 would thus be equal to false, as 1 is implicitly converted to
true and 2 is implicitly converted to true.
1 ^ 2 would on the other hand (still) be equal to 3, and 3 could be
implicitly converted to true.
Thus, the logical-xor operator (^^) would not behave the same as the
bitwise-xor operator (^).
// Anders
---
[ 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: neutron@attbi.com ("Jack Applin")
Date: Wed, 20 Aug 2003 02:52:46 +0000 (UTC) Raw View
Anders Dalvander (google@dalvander.com) wrote:
> Why are there no logical-xor operator (^^) in the language?
My xor FAQ follows.
Jack Applin
jack@hp.com
------------------------------------------------------------------------
People often ask why there isn't a logical exclusive-or 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.
The mythical ^^ operator can't do (2), but the others are possible.
Proposed code left-to-right? sequence point? bool args? bool result?
-------------- -------------- --------------- ---------- ------------
a ^ b no no no no
a != b no no no yes
(!a)!=(!b) no no yes yes
my_xor_func(a,b) no no yes yes
a ? !b : b yes yes yes no
a ? !b : !!b yes yes yes yes
The fact that you can achieve the same effect using a ? !b : !!b 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: stefan_heinzmann@yahoo.com (Stefan Heinzmann)
Date: Wed, 20 Aug 2003 14:19:47 +0000 (UTC) Raw View
google@dalvander.com (Anders Dalvander) wrote in message news:<d04c84a9.0308191319.32319a05@posting.google.com>...
> Why are there no logical-xor operator (^^) in the language?
Whenever I need one, I use != on boolean operands. That means, of
course, that I might have to explicitly convert the operands to
boolean, but I don't think that this is so inconvenient as to warrant
the introduction of a new operator.
In a nutshell, your proposed operator^^, if it existed, would
informally be implemented as follows:
template<typename L, typename R>
bool operator^^(const L& lhs, const R& rhs)
{
return bool(lhs) != bool(rhs);
}
Cheers
Stefan
---
[ 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, 21 Aug 2003 05:17:48 +0000 (UTC) Raw View
Jack Applin wrote:
> Proposed code left-to-right? sequence point? bool args? bool resu=
lt?
> -------------- -------------- --------------- ---------- ---------=
---
> a ^ b no no no no
> a !=3D b no no no yes
> (!a)!=3D(!b) no no yes yes
> my_xor_func(a,b) no no yes yes
> a ? !b : b yes yes yes no
> a ? !b : !!b yes yes yes yes
Consider:
#include <iostream>
using namespace std;
struct B
{
operator bool() const { return true; }
B operator!() const { return B(); }
};
int main()
{
B a, b;
cout << ( a ? !b : !!b ) << endl; // Oops...
cout << ( a ? !static_cast<bool>(b) : static_cast<bool>(b) ) << endl;
}
This also shows how the correct version should look like :)
Regards, Daniel
--=20
Daniel Frey
aixigo AG - financial training, research and 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: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Thu, 21 Aug 2003 17:24:57 +0000 (UTC) Raw View
An logxor (logical exclusive or) "operator" with the same precedence as
or can be implemented as a macro:
struct xor_dummy {};
struct xor_bool
{
template<typename T>
xor_bool(const T & value) : value(value) {}
const bool value;
};
template<typename T>
xor_bool operator or(T left, xor_dummy)
{
return xor_bool(left);
}
template<typename T>
bool operator or(xor_bool left, T right)
{
return left.value xor bool(right);
}
#define logxor or ::xor_dummy() or
---
[ 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: Fri, 22 Aug 2003 13:29:21 +0000 (UTC) Raw View
OK, the table needs some corrections, as I showed that the guarantees=20
given for bool args and bool results cannot be given by the proposed=20
code. Also, there is another important property for such an idiom: If=20
the arguments are integral constant expressions (ICEs), is the result=20
also guaranteed to be an integral constant expression? Obviously, this=20
is not given for a my_xor_func()-implementation. Another row should be=20
added to reflect whether the 'b'-part is repeated in the user's code or=20
not, as 'b' might be a long expression in practice, repeating it can be=20
a maintenance nightmare. Note that I ask "Singular 'b'" to make "yes"=20
the desirable answer. Here we go:
Proposed code left-to-right? sequence point? bool args? bool=20
result? ICE result? Singular 'b'?
-------------- -------------- --------------- ----------=20
------------ ----------- -------------
a ^ b no no no no=20
yes yes
a !=3D b no no no no=20
yes yes
(!a)!=3D(!b) no no no no=20
yes yes
my_xor_func(a,b) no no yes yes=20
no yes
a ? !b : b yes yes no no=20
yes no
a ? !b : !!b yes yes no no=20
yes no
[* see below] yes yes yes yes=20
yes no
(( a bool_xor b )) yes yes yes yes=20
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=20
macros that allow you such a strange syntax. Note that the=20
double-brackets are part of the syntax and cannot be removed! The set of=20
three macros (plus two internal helper macros) also provides bool_and=20
and bool_or. That given, what is it good for? We have && and || already,=20
why do we need such a stupid syntax? Well, && and || can't guarantee=20
that the arguments are converted to bool and that you get a bool result.=20
Think "operator overloads". 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(
Thanks to Paul Mensonides, Fernando Cacciola and John Torjo for feedback=20
on the code on the boost list :)
And please note that I never claimed someone could possibly need such=20
stuff :o)
Regards, Daniel
--=20
Daniel Frey
aixigo AG - financial training, research and 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 ]