22

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?

1
  • 1
    You can test it easily. I just did, and it looks like all the calls are made, not just the first.
    – Vilx-
    Commented Jan 26, 2012 at 16:04

4 Answers 4

52

It's bitwise OR assignment, not short-circuited OR evaluation.

It is equivalent to:

result = result | TryAndDoSomething(i);

Not:

result = result || TryAndDoSomething(i);
1
  • 1
    Probably the most accurate answer! +1 Commented May 23, 2018 at 12:04
27

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

2
  • @MooingDuck: This question only asks about booleans. I don't know whether the OP knows about bitwise-OR, and it doesn't appear important to what he's doing.
    – Ben Voigt
    Commented Jan 26, 2012 at 17:27
  • Id be happier with the answer if you said how they were different for non-booleans since the OP obviously doesnt know about bitwise-or (corrected typo) Commented Jan 26, 2012 at 17:33
8

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.

3
  • @MooingDuck: True. Edited to restrict to the OP’s context.
    – Jon Purdy
    Commented Jan 26, 2012 at 16:18
  • All you have to tell him is his interpretation is invalid. |= is the bitwise OR as you point out. So x |= 1 is the same as doing x = x | 1. X ||= 1; will not compile. Commented Jan 26, 2012 at 16:24
  • @Ramhound: Read the question again.
    – Jon Purdy
    Commented Jan 26, 2012 at 16:35
1

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).

1
  • @BenVoigt: Copy-Paste FTL! Thanks! Fix'd. Commented Jan 26, 2012 at 18:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.