9

Periodically, I wonder about this:

The short-circuit OR would always return the same value that the unshort-circuited OR operator would?

I expect that the short-circuit OR would always evaluate more quickly. So, was the unshort-circuited OR operator included in the C# language for consistency?

What have I missed?

Phil Helix
  • 1,966

5 Answers5

25

Both operands were meant for different things, coming from C which didn't have a boolean type. The short-circuit version || only works with booleans, while the non-short circuit version | works with integral types, performing a bitwise or. It just happened to work as a non-short circuit logical operation for booleans which are represented by a single bit, being 0 or 1.

http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical

Secure
  • 1,928
13

| (the bitwise-or) must be non-short-circuit for types like int. That is because in almost all cases you need to calculate both sides of an | expression to calculate the correct result. For example, what is the result of 7 | f(x) ?

If f(x) is not evaluated, you cannot tell.

Furthermore it would be inconsistent to make this operator short-circuit for bool, when it is non-short-circuit for int. By the way, I think I have never used | for logical comparisons intentionally, finding it is very inconvenient to speak of | as a logical operator.

|| however is for logical comparisons, where short-circuit evaluation works fine.

The same is valid even for C and C++, where the origin of those operators is.

Doc Brown
  • 218,378
5

This is correct, the short-circuit OR operator (||) will always return the same value as the non-short-circuit OR operator (|). (*)

However, if the first operand is true, the short-circuit operator will not cause evaluation of the second operand, while the non-short-circuit operator will always cause evaluation of both operands. This can have an impact on performance, and sometimes in side-effects.

So, there is a use for both: if you care for performance, and the evaluation of the second operand does not produce any side effects, (or if you do not care about them,) then by all means use the short-circuit operator. But if for some reason you need the side-effects of the second operand, then you should use the non-short-circuit operator.

An example where you should use the non-short-circuit operator:

if( write_customer_to_database() != SUCCESS |
    write_supplier_to_database() != SUCCESS |
    write_order_to_database() != SUCCESS )
{
    transaction_rollback();
}

(*) Except for some really perverted scenario where the evaluation of the first operand to false causes by side-effect the the second operand to evaluate to true instead of false.

Mike Nakis
  • 32,803
4

There would be 2 reasons to use the non-shortcircuit variant:

  1. keeping side effects (but that's clearer to code with a temporary variable)

  2. thwart timing attacks by avoiding the fork in the short circuit (this may even improve the runtime efficiency if the second operand is a variable but that is a micro-optimization the compiler may make anyway)

ratchet freak
  • 25,986
2

if the right-hand clause of the operator have side-effect, and the programmer intended that he want both side effect to happen before checking their return value.

Lie Ryan
  • 12,496