Operator |= for a boolean in C++ - c++

I stumbled upon the following construction in C++:
bool result = false;
for(int i = 0; i<n; i++){
result |= TryAndDoSomething(i);
}
I supposed that this |= was a shortcut for the OR operator, and that result would equal true in the end if at least one of these calls to TryAndDoSomething had returned true.
But now I am wondering if more than one call can actually return true. Indeed if we extend the operation as:
result = result || TryAndDoSomething(i);
Then the method will be called only if return evaluated to false, that is, if no other call before returned true. Thus after one call returning true, no other call will be done.
Is this the correct interpretation?

It's bitwise OR assignment, not short-circuited OR evaluation.
It is equivalent to:
result = result | TryAndDoSomething(i);
Not:
result = result || TryAndDoSomething(i);

On booleans, | yields the same result as ||, but doesn't short-circuit. The right operand of |= is always evaluated.

The only difference in this context between x |= f() (bitwise OR) and x = x || f() (logical OR) is that the latter is short-circuiting. In the former, f() will be executed n times—unless of course f() throws an exception, but that’s another story.
In the || version, f() will no longer be called once x becomes true. C++ does not have a ||= operator, but it is important to understand that |= and ||= (if it existed) would have different semantics because of this. |= is not just a replacement for the missing ||=.
As a side note, provided you are using bool, the bitwise operation is safe, because the standard specifies that true and false convert to the integers 1 and 0, respectively. So the only difference in this case is eager versus lazy evaluation.

result |= Try() is short for result = result | Try();. The || operator you seem to understand, but the | operator is quite different. It's name is bitwise or (as opposed to logical or). It has the same affect as if it performed a=a||b on each bit of the operands, and doesnt have the quick-bailout thing that logical and/or have. (It's also crazy fast; as fast or faster than addition). The other bitwise operations are & (bitwise and: a=a&&b on each bit), and ^ (bitwise xor: a=(a!=b) on each bit).

Related

What's the point of logical operators vs. bitwise operators

Given this statement is a logical operation
((a > 5) && (b > 4))
And this statement is bitwise-operation
((a > 5) & (b > 4))
Above two statements is not equivalent.
Because (a > 5) is an element of {0,1}
So, why do we need logical operators & bitwise-operation?
Edit: thanks for all of the feedback. Regarding the short circuit behaviour of logical operators, I actually do not want this behaviour - I am writing code for a GPU where branches degrade performance: short circuit results in two branches instead of one in the code.
For numerical comparisons in C, in the case where short circuit is not needed, it seems that logical and bitwise have identical behaviour. In my case, bitwise ops are faster than logical.
I apologize for not putting these details in the original posting.
I think no, take this example (0b - means binary):
a = 0b00000010
b = 0b00000100
Now, neither a nor b is 0. But a & b == 0 (due to the way bitwise AND is defined).
However a && b != 0 (because for logical AND result is 0 if at least one operand is 0 - this is not the case with a and b above).
Also there is short circuit evaluation, if in && left operand is 0, the right one will not be evaluated because result is certainly 0 (e.g., as already mentioned 0 && x == 0 no matter value of x).
The logical operators convert their operands to bool before combining them and the result of a logical operator is also bool all the time. The bitwise operators do not do this (however in case of operands that are bool anyway this doesn't make a difference between the two kind of operators).
Logical operators can be used on a lot of operand types that can be converted to bool while bitwise operators work only on a few types in specific cases and the output of bitwise operators are typed (not always bool).
the logical operators are shortcut. For example in case of && this means: if the first operand is false, then the second operand isn't even evaluated because the whole expression (false && something) is already false regardless of the value of the second operand.
The logical shortcut operators are often exploited in cases like the following:
// If mypointer is NULL, then mypointer->is_whatever()
// isn't evaluated so it doesn't cause a NULL pointer crash.
if (mypointer && mypointer->is_whatever()) {
// do my thing
}
Logical operators are to compare multiple values true-itiveness.
For example, you use the && operator to see if two values are both true.
Bit-wise operators are for isolating and modifying bits in a value.
For example, in order to turn off all the bits in an 8-bit value except for one, you would do this:
val & 00100000
In the above example, the 6th (1-based) or 5th (0-based) bit is kept as it was, and the other bits are turned off.
Both types of operators are similar in that they both either yield 0 or 1.
For example, take these:
1 || 0
The above would yield 1 because either of the values is equal to 1. However, if we switch the operator to &&, it would yield 0.
Out of all the operators you try, they will all either give 1 or 0, true or false. That is because there is no between: there is no such thing as an expression evaluating to "sort-of true" or "maybe false".
And I think the reason why a bit-wise operator always "yields" 1 or 0 is pretty self explanatory: bit-wise; a bit is either 1 or 0.
Not all expressions used as booleans evaluate to either 0 or 1; while 0 is treated as false, anything other than 0 is treated as true. So, for example, 1 && 2 would be true, but 1 & 2 would not, even though both 1 and 2 would be considered true.
Also, as others have pointed out, the logical operators will not evaluate the second expression if the first is enough to determine the overall value ('short-circuiting'), which obviously cannot be done with the bitwise version (well, not as often; 0 & ? will be 0 no matter what ? is, and thus ? wouldn't need to be evaluated to get the final value, but & doesn't work that way).

What logical AND operation does with stream output?

I just saw the code and I am unable to understand how the logical and behaves with "cout" here:
int userInput = 9; // Suppose user input is 9.
int remainder = 9 % 2;
(remainder & 1 && std::cout<<"odd" )|| cout<<"even";
std::cout<<"odd" is an expression that will return std::cout (which is why you can do std::cout << a << b << c). When evaluated in boolean context, it simply returns true if the fail bit isn't set. So if the output operation succeeds then it will evaluate as true.
However, the intent of this code isn't to test that value, rather it is a clever (and not very readable)1 way to express this:
if (remainder & 1) {
std::cout << "odd";
} else {
std::cout << "even";
}
It takes advantage of the short-circuiting nature of the && and || operators:
In a && b, if a is false then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
In a || b, if a is true then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
So if remainder & 1 evaluates as false (zero in this case) then std::cout << "odd" is not evaluated because the && expression short-circuits, returning false. This is the left operand to the outer || expression, which causes its b (std::cout << "even") to be evaluated, writing "even" to the output.
If remainder & 1 evaluates as true (non-zero in this case) then the right operand for && is evaluated, displaying "odd". Assuming that this operation succeeds, the left operand for the || operation will be true, which causes it to short-circuit and not evaluate the right operand.
1 Experienced programmers are likely to know exactly what is going on here, but as you have found this technique is not the most readable. It's better (IMO) to be straightforward about the intent of code, so I would just use an if conditional -- or, at the very least, use the ternary operator: std::cout << (remainder & 1 ? "odd" : "even").
In other languages (JavaScript comes to mind) (ab)using the short-circuiting operators is a very common technique. I usually don't see them used this way in C++ and I would strongly discourage such use.
The line in question:
(remainder & 1 && std::cout<<"odd" ) || cout<<"even";
Is the same as the following when you take operator precedence and operator overloads into account:
((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool());
std::cout (more generically, std::basic_ostream) has operator<<() and operator bool() operators defined. The first operator returns a std::basic_ostream& reference, ie a reference to the stream itself (useful for chaining operations together). The second operator returns whether the stream is in a failure state or not.
See the following documentation for more details:
C++ operator precedence
operator overloading
std::basic_ostream::operator<<
std::basic_ios::operator bool

Is &= guaranteed to behave like hypothetical &&= operator?

sometimes I would like to do
bool success= true;
success &&= dosmthing1();
success &&= dosmthing2();
success &&= dosmthing3();
if (success)
Lets ignore that I could be using exceptions...
my question is is it guaranteed by C++ standard that &= will behave like nonexisting &&= for my use case?
...
EDIT: do smthing-s return bool
That depends on how you expect &&= to work. If you want x &&= y(); to be equivalent to x = x && y();, then no, because in this expression y() is not called if x starts out as false, but in x &= y(); it will be.
If you don't expect it to be short-circuiting and all your expression really have type bool (not something convertible to bool, like pointers, integers, or user-defined objects), it works. That's a lot of restrictions though.
No, & is a bitwise and, && is boolean and. If dosmthing* returns something other than 1 or 0, the results will be different.
No; it isn't short-circuiting.
bool x = false;
x &= (cout << "You shouldn't see me!");
They are completely different. In this case, the short
circuiting of && seems important: if dosmthing1() returns
false, dosmthing2 and dosmthing3 would not be called if you
use &&. They will be called if you use &.
In this particular case, why not just write:
success = dosmthing1()
&& dosmthing2()
&& dosmthing3();
This seems just as clear (at least formatted like this), and
avoids any need for &&=.

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

& has &&. | has ||. Why doesn't ^ have ^^?
I understand that it wouldn't be short-circuiting, but it would have different semantics. In C, true is really any non-zero value. Bitwise XOR is not always the same thing as logical XOR:
int a=strcmp(str1,str2);// evaluates to 1, which is "true"
int b=strcmp(str1,str3);// evaluates to 2, which is also "true"
int c=a ^^ b; // this would be false, since true ^ true = false
int d=a ^ b; //oops, this is true again, it is 3 (^ is bitwise)
Since you can't always rely on a true value being 1 or -1, wouldn't a ^^ operator be very helpful? I often have to do strange things like this:
if(!!a ^ !!b) // looks strange
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.
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.
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 ...

Using bitwise operators for Booleans in C++

Is there any reason not to use the bitwise operators &, |, and ^ for "bool" values in C++?
I sometimes run into situations where I want exactly one of two conditions to be true (XOR), so I just throw the ^ operator into a conditional expression. I also sometimes want all parts of a condition to be evaluated whether the result is true or not (rather than short-circuiting), so I use & and |. I also need to accumulate Boolean values sometimes, and &= and |= can be quite useful.
I've gotten a few raised eyebrows when doing this, but the code is still meaningful and cleaner than it would be otherwise. Is there any reason NOT to use these for bools? Are there any modern compilers that give bad results for this?
|| and && are boolean operators and the built-in ones are guaranteed to return either true or false. Nothing else.
|, & and ^ are bitwise operators. When the domain of numbers you operate on is just 1 and 0, then they are exactly the same, but in cases where your booleans are not strictly 1 and 0 – as is the case with the C language – you may end up with some behavior you didn't want. For instance:
BOOL two = 2;
BOOL one = 1;
BOOL and = two & one; //and = 0
BOOL cand = two && one; //cand = 1
In C++, however, the bool type is guaranteed to be only either a true or a false (which convert implicitly to respectively 1 and 0), so it's less of a worry from this stance, but the fact that people aren't used to seeing such things in code makes a good argument for not doing it. Just say b = b && x and be done with it.
Two main reasons. In short, consider carefully; there could be a good reason for it, but if there is be VERY explicit in your comments because it can be brittle and, as you say yourself, people aren't generally used to seeing code like this.
Bitwise xor != Logical xor (except for 0 and 1)
Firstly, if you are operating on values other than false and true (or 0 and 1, as integers), the ^ operator can introduce behavior not equivalent to a logical xor. For example:
int one = 1;
int two = 2;
// bitwise xor
if (one ^ two)
{
// executes because expression = 3 and any non-zero integer evaluates to true
}
// logical xor; more correctly would be coded as
// if (bool(one) != bool(two))
// but spelled out to be explicit in the context of the problem
if ((one && !two) || (!one && two))
{
// does not execute b/c expression = ((true && false) || (false && true))
// which evaluates to false
}
Credit to user #Patrick for expressing this first.
Order of operations
Second, |, &, and ^, as bitwise operators, do not short-circuit. In addition, multiple bitwise operators chained together in a single statement -- even with explicit parentheses -- can be reordered by optimizing compilers, because all 3 operations are normally commutative. This is important if the order of the operations matters.
In other words
bool result = true;
result = result && a() && b();
// will not call a() if result false, will not call b() if result or a() false
will not always give the same result (or end state) as
bool result = true;
result &= (a() & b());
// a() and b() both will be called, but not necessarily in that order in an
// optimizing compiler
This is especially important because you may not control methods a() and b(), or somebody else may come along and change them later not understanding the dependency, and cause a nasty (and often release-build only) bug.
The raised eyebrows should tell you enough to stop doing it. You don't write the code for the compiler, you write it for your fellow programmers first and then for the compiler. Even if the compilers work, surprising other people is not what you want - bitwise operators are for bit operations not for bools.
I suppose you also eat apples with a fork? It works but it surprises people so it's better not to do it.
I think
a != b
is what you want
Disadvantages of the bitlevel operators.
You ask:
“Is there any reason not to use the bitwise operators &, |, and ^ for "bool" values in C++? ”
Yes, the logical operators, that is the built-in high level boolean operators !, && and ||, offer the following advantages:
Guaranteed conversion of arguments to bool, i.e. to 0 and 1 ordinal value.
Guaranteed short circuit evaluation where expression evaluation stops as soon as the final result is known.
This can be interpreted as a tree-value logic, with True, False and Indeterminate.
Readable textual equivalents not, and and or, even if I don't use them myself.
As reader Antimony notes in a comment also the bitlevel operators have alternative tokens, namely bitand, bitor, xor and compl, but in my opinion these are less readable than and, or and not.
Simply put, each such advantage of the high level operators is a disadvantage of the bitlevel operators.
In particular, since the bitwise operators lack argument conversion to 0/1 you get e.g. 1 & 2 → 0, while 1 && 2 → true. Also ^, bitwise exclusive or, can misbehave in this way. Regarded as boolean values 1 and 2 are the same, namely true, but regarded as bitpatterns they're different.
How to express logical either/or in C++.
You then provide a bit of background for the question,
“I sometimes run into situations where I want exactly one of two conditions to be true (XOR), so I just throw the ^ operator into a conditional expression.”
Well, the bitwise operators have higher precedence than the logical operators. This means in particular that in a mixed expression such as
a && b ^ c
you get the perhaps unexpected result a && (b ^ c).
Instead write just
(a && b) != c
expressing more concisely what you mean.
For the multiple argument either/or there is no C++ operator that does the job. For example, if you write a ^ b ^ c than that is not an expression that says “either a, b or c is true“. Instead it says, “An odd number of a, b and c are true“, which might be 1 of them or all 3…
To express the general either/or when a, b and c are of type bool, just write
(a + b + c) == 1
or, with non-bool arguments, convert them to bool:
(!!a + !!b + !!c) == 1
Using &= to accumulate boolean results.
You further elaborate,
“I also need to accumulate Boolean values sometimes, and &= and |=? can be quite useful.”
Well, this corresponds to checking whether respectively all or any condition is satisfied, and de Morgan’s law tells you how to go from one to the other. I.e. you only need one of them. You could in principle use *= as a &&=-operator (for as good old George Boole discovered, logical AND can very easily be expressed as multiplication), but I think that that would perplex and perhaps mislead maintainers of the code.
Consider also:
struct Bool
{
bool value;
void operator&=( bool const v ) { value = value && v; }
operator bool() const { return value; }
};
#include <iostream>
int main()
{
using namespace std;
Bool a = {true};
a &= true || false;
a &= 1234;
cout << boolalpha << a << endl;
bool b = {true};
b &= true || false;
b &= 1234;
cout << boolalpha << b << endl;
}
Output with Visual C++ 11.0 and g++ 4.7.1:
true
false
The reason for the difference in results is that the bitlevel &= does not provide a conversion to bool of its right hand side argument.
So, which of these results do you desire for your use of &=?
If the former, true, then better define an operator (e.g. as above) or named function, or use an explicit conversion of the right hand side expression, or write the update in full.
Contrary to Patrick's answer, C++ has no ^^ operator for performing a short-circuiting exclusive or. If you think about it for a second, having a ^^ operator wouldn't make sense anyway: with exclusive or, the result always depends on both operands. However, Patrick's warning about non-bool "Boolean" types holds equally well when comparing 1 & 2 to 1 && 2. One classic example of this is the Windows GetMessage() function, which returns a tri-state BOOL: nonzero, 0, or -1.
Using & instead of && and | instead of || is not an uncommon typo, so if you are deliberately doing it, it deserves a comment saying why.
Patrick made good points, and I'm not going to repeat them. However might I suggest reducing 'if' statements to readable english wherever possible by using well-named boolean vars.For example, and this is using boolean operators but you could equally use bitwise and name the bools appropriately:
bool onlyAIsTrue = (a && !b); // you could use bitwise XOR here
bool onlyBIsTrue = (b && !a); // and not need this second line
if (onlyAIsTrue || onlyBIsTrue)
{
.. stuff ..
}
You might think that using a boolean seems unnecessary, but it helps with two main things:
Your code is easier to understand because the intermediate boolean for the 'if' condition makes the intention of the condition more explicit.
If you are using non-standard or unexpected code, such as bitwise operators on boolean values, people can much more easily see why you've done this.
EDIT: You didnt explicitly say you wanted the conditionals for 'if' statements (although this seems most likely), that was my assumption. But my suggestion of an intermediate boolean value still stands.
Using bitwise operations for bool helps save unnecessary branch prediction logic by the processor, resulting from a 'cmp' instruction brought in by logical operations.
Replacing the logical with bitwise operations (where all operands are bool) generates more efficient code offering the same result. The efficiency ideally should outweigh all the short-circuit benefits that can be leveraged in the ordering using logical operations.
This can make code a bit un-readable albeit the programmer should comment it with reasons why it was done so.
IIRC, many C++ compilers will warn when attempting to cast the result of a bitwise operation as a bool. You would have to use a type cast to make the compiler happy.
Using a bitwise operation in an if expression would serve the same criticism, though perhaps not by the compiler. Any non-zero value is considered true, so something like "if (7 & 3)" will be true. This behavior may be acceptable in Perl, but C/C++ are very explicit languages. I think the Spock eyebrow is due diligence. :) I would append "== 0" or "!= 0" to make it perfectly clear what your objective was.
But anyway, it sounds like a personal preference. I would run the code through lint or similar tool and see if it also thinks it's an unwise strategy. Personally, it reads like a coding mistake.