Why is there no ^^ operator in C/C++?

自作多情 提交于 2019-11-29 03:26:39
Don

Dennis Ritchie answers

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.
[...]
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.

John Rasch

Technically, one already exists:

a != b

since this will evaluate to true if the truth value of the operands differ.

Edit:

Volte's comment:

(!a) != (!b)

is correct because my answer above does not work for int types. I will delete mine if he adds his answer.

Edit again:

Maybe I'm forgetting something from C++, but the more I think about this, the more I wonder why you would ever write if (1 ^ 2) in the first place. The purpose for ^ is to exclusive-or two numbers together (which evaluates to another number), not convert them to boolean values and compare their truth values.

This seems like it would be an odd assumption for a language designer to make.

For non-bool operands, I guess what you would want is for a ^^ b to be evaluated as:

(a != 0) ^ (b != 0)

Well, you have the above option and you have a few options listed in other answers.

The operator ^^ would be redundant for bool operands. Talking only about boolean operands, for the sake of argument, let's pretend that ^ was bitwise-only and that ^^ existed as a logical XOR. You then have these choices:

  • & - Bitwise AND -- always evaluates both operands
  • && - Logical AND -- does not always evaluate both operands
  • | - Bitwise OR -- always evaluates both operands
  • || - Logical OR -- does not always evaluate both operands
  • ^ - Bitwise XOR -- must always evaluate both operands
  • ^^ - Logical XOR -- must always evaluate both operands

Why didn't they create ^^ to essentially convert numerical values into bools and then act as ^? That's a good question. Perhaps because it's more potentially confusing than && and ||, perhaps because you can easily construct the equivalent of ^^ with other operators.

Jay

I can't say what was in the heads of Kernighan and Ritchie when they invented C, but you made a brief reference to "wouldn't be short-circuiting", and I'm guessing that's the reason: It's not possible to implement it consistently. You can't short-circuit XOR like you can AND and OR, so ^^ could not fully parallel && and ||. So the authors might well have decided that making an operation that sort of kind of looks like its parallel to the others but isn't quite would be worse than not having it at all.

Personally, the main reason I use && and || is for the short-circuit rather than the non-bitwise. Actually I very rarely use the bitwise operators at all.

Another workaround to the ones posted above (even if it requires another branch in the code) would be:

if ( (a? !b : b ) )

that is equivalent to xor.

In Java the ^ operator indeed does do logical XOR when used on two boolean operands (just like & and | in Java do non-short-circuiting logical AND and OR, respectively, when applied to booleans). The main difference with C / C++ is that C / C++ allows you to mix integers and booleans, whereas Java doesn't.

But I think it's bad practice to use integers as booleans anyway. If you want to do logical operations, you should stick to either bool values, or integers that are either 0 or 1. Then ^ works fine as logical XOR.

An analogous question would be to ask, how would you do non-short-circuiting logical AND and OR in C / C++? The usual answer is to use the & and | operators respectively. But again, this depends on the values being bool or either 0 or 1. If you allow any integer values, then this does not work either.

Regardless of the case for or against ^^ as an operator, you example with strcmp() sucks. It does not return a truth value (true or false), it returns a relation between its inputs, encoded as an integer.

Sure, any integer can be interpreted as a truth value in C, in which case 0 is "false" and all other values are "true", but that is the opposite of what strcmp() returns.

Your example should begin:

int a = strcmp(str1, str2) == 0; // evaluates to 0, which is "false"
int b = strcmp(str1, str3) == 0; // evaluates to 0, which is also "false"

You must compare the return value with 0 to convert it to a proper boolean value indicating if the strings were equal or not.

With "proper" booleans, represented canonically as 0 or 1, the bitwise ^ operator works a lot better, too ...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!