Search code examples
c#cshort-circuiting

In C, is single & and single | valid so as to avoid short circuit? Also please give some examples of utility of same in C#


&& is logical AND and || is Logical OR

In C#, for example,

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num>=0&&num<=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

Now for && only if both the conditions are true, then the if block gets executed, else else block gets executed.

So for input 2 conditions num>=0 and num<=10 are both true. So condition num>=0&&num<=10 is true and if statement gets executed. get output Hi.

For input -2 condition num<=10 is true but condition num>=0 is false. Since both the conditions should be true, condition num>=0 && num<=10 is false so instead of for statement else statement gets executed. So the output is Hello.

For input 12 condition num>=0 is true but condition num<=10 is false. Since both the conditions should be true, condition num>=0 && num<=10 is false so instead of for statement else statement gets executed. So the output is Hello.

Now, in this case if the first condition num>=0 comes out to be flase compiler does not check the second condition num<=10, since in case of && if both the conditions are true, only then num>=0&&num<=10 is true.

Now consider the following program -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num>=0&num<=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

Here instead of &&, & is given

The output will be same as the truth table for && and & are same.

But here, during evaluation of the condition num>=0&num=<10, if the input is -2, then first condition num>=0 is false. But unlike && even after first condition is false second condition num<=10 is evaluated, and then the control passes on to the next statement.


Similarly for logical OR; consider the following C# example -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num<=0||num>=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

If input is -2, first condition num<=0 is true and second condition num>=10 is false. Since in || num<=0||num>=10 is true if either of the two statements are true, so if block gets executed and the ouput is Hi.

If input is 12 first condition num<=0 is false but second condition num>=10 is true. For || num<=0||num>=10 is true if either condition is true, so if block gets executed and the output is Hi.

If input is 2 first condition num<=0 is false. Also second condition num>=10 is false. Since both the conditions are false num<=0||num>=10 is flase and else block gets executed. So output is Hello.

Now consider the following program -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num<=0|num>=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

Here instead of || | is used. Both the programs generate same output as truth tables of || and | are same.

But when || is used and if input is -2, first condition num<=0 is true. Since for num<=0||num>=10 to be true either conditions needs to be true and first condition num<=0 is already true, compiler doesn't check the second condition num>=10

But when | is used and here also the input is -2, even after evaluating the first condition num<=0 to be true, compiler checks the second condition num>=10


Concept of ""Short Circuit" in C

Let us consider the following example -

#include <stdio.h>
int main() {
    int a, b, c;
    a = -1;
    b = 0;
    c = ++a && ++b;
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    return 0;
}

Expected output:

a = 0, b = 1, c = 0

Real output:

a = 0, b = 0, c = 0

It is because in the statement c = ++a && ++b; when the value of a is incremented by 1 it's new value is 0. 0 is evaluated to be false. In && the whole condition is false if either the first condition or second condition is false. So here as ++a is evaluated to be false the condition ++b is never checked by the compiler. So b is never incremented and its value stays 0

Now consider the following example -

#include <stdio.h>

int main() {
    int a, b, c;
    a = 0;
    b = 10;
    c = ++a || ++b;
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    return 0;
}

Expected output:

a = 1, b = 11, c = 1

Real output:

a = 1, b = 10, c = 1

Here in the statement

c = ++a || ++b;

++a is 1 and 1 is evaluated as true. In || the whole condition is true if either the first condition or second condition is true. Here since first condition ++a is true, second condition ++b is never checked by the compiler. So the value of b is never incremented and stays 10.


Now, my question -

  1. Is & and | valid in C so that short circuit can be avoided?

  2. In C# bool can only be true, false or null. Unlike C 0 is not false and all non-zero value is not true. So short circuit can never take place in C#. So in C# what is the utility of & and |?


Solution

  • Here are the answers to your questions:

    Is & and | valid in C so that short circuit can be avoided?

    No. The & and | operators in C mean different things compared to their C# logical counterparts.

    In C, & and | are bitwise operators. They will evaluate both the sides and combine the bits of the resulting values according to the operator. Afterwards, if the resulting value is used in a logical context it will be processed as 0=false, everything else=true.

    This is not the same as short-circuit logical operators as C# have.

    In C# bool can only be true, false or null. Unlike C 0 is not false and all non-zero value is not true. So short circuit can never take place in C#.

    So in C# what is the utility of & and |?

    The purpose of & and | as logical operators in C# is to support non-short-circuit evaluation.

    Take this example:

    // s is string
    if (s != null && s.Length > 0) { ... }
    

    Here, if s is indeed null, the value of the first operand is false, hence the whole expression can never be true and thus the second operand, s.Length > 0 is not evaluated.

    Contrast to this:

    if (s != null & s.Length > 0) { ... }
    

    Observe that I switched to the non-short-circuit & operator here. Here, if s is null, both operands will still be evaluated and the code will throw a NullReferenceException.

    In some situations, it may be beneficial and required that you evaluate both sides even if you know the result will never be false regardless of what the second operand says. In those situations, you would use the non-short-circuit operators.


    In C, the operators mean this:

    • | = bitwise OR operator
    • & = bitwise AND operator
    • || = logical OR operator that short circuits
    • && = logical AND operator that short circuits

    In C#, the operators mean this:

    • | = bitwise OR operator if applied to integers, logical non-short-circuit OR operator if applied to bools
    • & = bitwise AND operator if applied to integers, logical non-short-circuit AND operator if applied to bools
    • || = logical OR operator that short circuits
    • && = logical AND operator that short circuits