Behaviour of && in C programming language

10,915

Solution 1

Because of Short-circuit evaluation, when x is 0, y and z don't really need to be evaluated since 0 && ANYTHING is 0.

Once x is incremented to 0, the result is 0, and that's what y gets.

z remains unchanged (-1).


 x  | y  |  z 
----+----+-----
 -1 | -1 | -1   //x = y = z = -1;  
  0 | -1 | -1   //++x && ... Now the whole expression is evaluated to 0
  0 |  0 | -1   //y = ++x && ++y && ++z;

Solution 2

I only can think about that && evaluates in short circuit: given A && B, if A evaluates false then B is not evaluated.

So:

X becomes 0. && ++y && ++z does not evaluates since X/0/false && ...

y=0 as assigned from y = x/0/false

z remains unmodified since ++z does not get executed.

Solution 3

&& operator is evaluated pairwise, therefore I'm guessing C is evaluating

((++x && ++y) && ++z)

now, ++x will return zero therefore the first && will fail as will the second one without the need to evaluate ++y or ++z.

y = 0 since that is the result of the expression.

z is not touched

Solution 4

For completeness (brain dump):

The term behind this sorcery is called short circuiting. Let's go over your code and then a brief blurb about why this happens. Looking at:

int main( void ) {  
  int x, y, z;
  x = y = z = -1;
  y = ++x && ++y && ++z;

  printf( "x = %d, y = %d, z = %d, x, y, z );

  return 0;  
}

... we begin to break it down line by line. The first line:

int x, y, z;

... declares three integers, x, y and z. They are initialized to garbage values on the stack frame because there is no initialization (assignment operator). This line does not really matter, now let's look at the next one:

 x = y = z = -1;

... we see that we are doing multiple assignments on the same line. Recall that the assignment operator will mutate the identifier to the left of the assignment operator (using the value to the right of the assignment operator) and return the value of x. This is known as assignment overloading. But again, this does not really matter -- the only important thing to realize is x, y and z are now all -1. Let's look at the next line:

 y = ++x && ++y && ++z;

... Sorcery Yoda says. Let's add the parenthesis to make it more obvious which step is being evaluated first:

 y = ( ( ++x ) && ++y && ++z );

... now looking at the inner-most parenthesis we see that it's a prefix increment of x, meaning we will increment the value of x and then return it. We note that x is originally -1 and it is now 0 after being incremented. This will resolve as follows:

 y = ( 0 && ++y && ++z );

... now it's important to note that looking at our truth tables:

A | B | A && B
--------------
T | T |   T
T | F |   F
F | T |   F
F | F |   F

... for the AND logical operator we see that both F (AND) T, T (AND) F are F. The compiler realizes this and short circuits when ever it is evaluating a conjunction (AND) where a value is false -- a clever technique of optimization. It will then resolve to assigning y to be 0 (which is false). Recall that in C any non-zero value is true, only 0 is false. The line will look as follows:

 y = 0;

... now looking at the next line:

 printf( "x = %d, y = %d, z = %d, x, y, z );

... it should be obvious to you now that it will output x = 0, y = 0, z = -1.

Solution 5

What happens is that ++y and ++z are never evaluated because the first part already ensures what the new value of y will be.

The first part of your statement is ++x && ... which is equivalent to 0 && ... and then we already know that y will be 0 in the end so the rest of the statement is not executed.

if you did this:

int main(){  
  int x,y,z,tmp;  
  x = y = z = -1;  
  tmp = ++x && ++y && ++z;  
  printf("x = %d, y = %d, z = %d, tmp = %d", x,y,z, tmp);  
  return 0;  
} 

You would get x = 0, y = -1, z = -1, tmp = 0

The left evaluation is guaranteed in the C99 standard. You can find it in the section 6.5.13 Logical AND operator

Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares equal to 0, the second operand is not evaluated.

You can find more information about what is a sequence point on Wikipedia or in the Annex C of the C99 standard

Share:
10,915

Related videos on Youtube

Mayank Tiwari
Author by

Mayank Tiwari

I am Mayank Tiwari Pursuing M. Tech from Indian Institute of Information Technology Design And Manufacturing Jabapur.

Updated on June 03, 2022

Comments

  • Mayank Tiwari
    Mayank Tiwari almost 2 years

    I am beginner in C programming language, recently I have read about Logical AND && operator.

    I also know that, in C programming language all non-zero values are treated as TRUE.

    NON-ZERO && NON-ZERO = 1  
    NON-ZERO && ZERO = 0  
    ZERO && NON-ZERO = 0
    ZERO && ZERO = 0  
    

    But when I am dealing with the following program then I am not getting expected answer.

    int main(){  
      int x, y, z;  
      x = y = z = -1;  
      y = ++x && ++y && ++z;  
      printf("x = %d, y = %d, z = %d, x, y, z);  
      return 0;  
    } 
    

    I am expecting

    x = 0, y = 0, z = 0 
    

    but the answer is

    x = 0, y = 0, z = -1
    

    Can anyone please explain, Why I am getting this answer?

    Edit: In this question, I have not asked about the precedence of operators.

    • Mayank Tiwari
      Mayank Tiwari over 10 years
      down voter and people who will wish to close this question, kindly dare to put your comments.
    • devnull
      devnull over 10 years
    • fuz
      fuz over 10 years
      I smell undefined behavior...
    • Omkant
      Omkant over 10 years
      Not in this case I think ...but if x evaluates to true then it will be undefined behaviour.. correct me if I am wrong
    • devnull
      devnull over 10 years
      @FUZxxl What is undefined here?
    • fuz
      fuz over 10 years
      @devnull I am not quite sure but short circuit evaluation plus increment operators looks like the ideal recipe to get surprising or undefined behavior. Beware of nasal demons.
    • Yu Hao
      Yu Hao over 10 years
      @FUZxxl No, shot circuit of && makes sure the calculation sequence of this expression, so no undefined behavior.
    • devnull
      devnull over 10 years
      @FUZxxl You're right; I'm surprised that the question remains open. (I was attempting to say that there isn't anything undefined in this case.)
    • Mayank Tiwari
      Mayank Tiwari over 10 years
      @devnull, check the whole question from the link suggested by you, and please tell me where you have found y = ++x && ++y && ++z; please inform me if you find so.
    • devnull
      devnull over 10 years
      @user2320537 An assignment doesn't make this question unique.
    • Mayank Tiwari
      Mayank Tiwari over 10 years
      @devnull, yes you are right, but just based on a simple line of another question you can not directly say it is duplicate of.
    • phuclv
      phuclv over 5 years
    • Mayank Tiwari
      Mayank Tiwari over 5 years
      @phuclv, not at all...
    • phuclv
      phuclv over 5 years
      operator precedence aside, the root cause is the same which is all about short circuit evaluation. Other duplicates: Explanation for this function's output, stackoverflow.com/q/31265625/995714, stackoverflow.com/q/7196013/995714...