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?

  • 9
    Same return value - yes. Same side effects - no.
    – Job
    Commented Dec 25, 2011 at 18:01
  • 2
    Suppose f() raises an exception, consider true || f() and true | f(). Do you see the difference? The former expression evaluates to true, evaluation of the latter results in an exception being thrown.
    – scarfridge
    Commented Apr 20, 2012 at 10:39

5 Answers 5


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.


  • 10
    +1 for the link. When I read this question I was like "what?" since afaik the official name of these are logical and bitwise or, and not short-circuit and unshort-circuit which happen to be side-effects of how they work.
    – stijn
    Commented Dec 25, 2011 at 10:21
  • 1
    +1 I see "operates on boolean operands only" - I possibly did not notice the difference because I only use expressions that evaluate to Boolean anyway
    – Phil Helix
    Commented Dec 25, 2011 at 11:16
  • 2
    I had to check, but it is in fact true that the | operator, when applied to two boolean values, is compiled into the same or operator in CIL as it is when applied to two integer values - unlike || which is compiled into CIL using brtrue for a conditional jump. Commented Dec 25, 2011 at 11:20

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


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 )

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

  • 2
    +1 But I'd like to add that apart from using functions to indicate success or failure (as in your example): functions with side effects should generally be avoided... Commented Dec 25, 2011 at 9:49
  • 1
    Yes, that's probably why I have never used any of the non-short-circuit operators up until today, and the chances are slim that I ever will.
    – Mike Nakis
    Commented Dec 25, 2011 at 9:58
  • That example depends on the operands being evaluated in strict left-to-right order. C# does guarantee this, but many similar languages (including C and C++) do not. Commented Dec 25, 2011 at 10:18
  • Wouldn't short-circuit evaluation make sense for that particular example, since all the transactions will be rolled back if any of them fails? (I'm making some assumptions about the semantics of the calls.) Commented Dec 25, 2011 at 10:20
  • @KeithThompson you are right, non-short-circuit evaluation will cause unnecessary processing, and in this sense the example is a bit lame, but it is not so lame as to warrant changing, because the truth remains that with short-circuit evaluation if write_customer_to_database() succeeds, then the rest of the write_... functions will never be called, and it is better to work correctly in the case of success, than to perform some unnecessary operations in the case of failure.
    – Mike Nakis
    Commented Dec 25, 2011 at 11:25

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)

  • This is the only right reason provided, I have no idea why this isn't the accepted answer with highest votes...
    – Behrooz
    Commented Jul 5, 2015 at 8:51

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.

  • 5
    Eek. Please don’t code like that … if you rely on side effects, have two different expressions, assign the results, and test them afterwards. Commented Dec 25, 2011 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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