2

I understand that single bar evaluates both sides regardless and double bar only evaluates the right sided conditional if the left side evaluates to false but I can't in my right mind find any instances where the variation in use would have an effect on my code.

Does anyone have any visual examples to help me better understand if there is any significance in this difference between these operators?

  • Double bar || is pretty ubiquitous in high-level programming and is used due to performance reasons. It takes time to evaluate whatever is on the left and right side of the operator. If you only have to evaluate one expression this is naturally faster. – HerSta Aug 16 '21 at 11:50
  • [Logical and Bitwise Operators in C#](https://www.pluralsight.com/guides/logical-and-bitwise-operators-in-c) • [Boolean Algebra](https://dev.to/stefandurlesteanu/boolean-algebra-for-dummies-nno) • [Boolean logic](https://www.bbc.co.uk/bitesize/guides/zqp9kqt/revision/1) • [Boolean Logic](https://introcs.cs.princeton.edu/java/71boolean/) • [Boolean algebra](https://en.wikipedia.org/wiki/Boolean_algebra) • [C# Bitwise Operators](https://www.tutorialspoint.com/csharp/csharp_bitwise_operators.htm) • [C# Bitwise & Bit Shift Operators](https://www.programiz.com/csharp-programming/bitwise-operators) –  Aug 16 '21 at 11:50
  • @HerSta Performance is often _not_ the primary reason. It is _a_ reason yes. – mjwills Aug 16 '21 at 11:54
  • @HerSta There are very rare situations in high-performance algorithms where `|` is preferable, due to branch mispredictions at the CPU level, see https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-processing-an-unsorted-array – Charlieface Aug 16 '21 at 12:04
  • Neither of the duplicates actually answer the question. The OP already knows what's in those answers, but they were asking for an example that demonstrated a difference at runtime. – Matthew Watson Aug 16 '21 at 12:14
  • @MatthewWatson OP wrote "*I understand that single bar evaluates both sides regardless and double bar only evaluates the right sided conditional if the left side evaluates to false*" and you wrote "*OP already knows what's in those answers*" but I don't think coz it's not the subject of bitwise and logical operators that one evaluates the whole statement or that the other evaluates the operands one after the other, coz the first is on low-lvl bit calculation and the later about high comparing TRUE and FALSE as the result of a comparison condition. Therefore duplicates answer the OP's question. –  Aug 16 '21 at 12:41
  • @MatthewWatson Thus logical operators are evaluated from right to left until the final result for performance reasons because it is not necessary to continue once you have obtained one result that will not be affected by the evaluation of the next. And this is to be taken into consideration when calling methods or doing assignements in such operands of conditional statements whether with IFs or ternary or assignments... That's the difference at runtime that bitwise is calculation on bits and logical is comparison of conditionals. –  Aug 16 '21 at 12:46
  • @OlivierRogier `Thus logical operators are evaluated from right to left` You mean left to right, surely? Anyway, the OP was after an example showing a practical difference. – Matthew Watson Aug 16 '21 at 14:36
  • Yes, it's just a typo: *Thus logical operators are evaluated from left to right until the final result for performance reasons*. –  Aug 16 '21 at 14:41
  • `but they were asking for an example that demonstrated a difference at runtime.` Well the duplicate I added shows an example @MatthewWatson. Search in them for `so while the following is safe:`. It is very similar to the example in your below answer. – mjwills Aug 17 '21 at 00:34

2 Answers2

2

Consider the following code:

public static void Main()
{
    string test = null;

    if (test == null || test.Length == 0) // Doesn't crash.
        Console.WriteLine("A");

    if (test == null | test.Length == 0) // Does crash.
        Console.WriteLine("B");
}

The second if will crash because it will try to evaluate test.Length when test is null.

And anything where the code after the | has side-effects will have different results, of course.

For example, this prints 1:

int value = 0;

if (value == 0 | ++value == 0)
    Console.WriteLine(value);

And this prints 0:

int value = 0;

if (value == 0 || ++value == 0)
    Console.WriteLine(value);
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thank you, the kind of precise nuances I needed. Didn't think of the relevance of the relationship shared between conditions. Appreciate your time answering. – Newporteeze Aug 16 '21 at 11:57
  • Glad I could help. Judging from the downvote, it appears that there's someone around that doesn't like people giving this kind of help... – Matthew Watson Aug 16 '21 at 12:16
  • 2
    Unfortunately I don't have enough reputation to negate that, but thanks again. Seemingly it's assumed this question has been asked before but the examples are not the same. Seemingly missing the point of this question completely. – Newporteeze Aug 16 '21 at 12:44
  • @Newportsleeze It has no importance. –  Aug 16 '21 at 12:58
2

An example could be bool IEnumerator.MoveNext()

It does two things:

  • Advances the enumerator to the next element of the collection.
  • returns a bool: "true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection."

A usuall way to process Emuerators is while(EnumeratorInstance.MoveNext()). But if you add a 2nd condition that is checked first, like continueEnumerating == true you would get different results - namely the Enumerator advancing even if you do not need to.

Note that overall in my experience the single variant is less common exactly because it incurs side effects. For clarity if I want both sides to execute, I would use bool moreStuffToRead = EnumeratorInstance.MoveNext(); and then check for both bool values with a ||. But that is just personal preference. I value understandable code above all else, even performance.

Christopher
  • 9,634
  • 2
  • 17
  • 31
  • Appreciate the comment. I like the example, taught me a new Method and got me thinking about its relevance. Cheers. – Newporteeze Aug 16 '21 at 12:04