Explain the apparent conflict between && and || and the actual result of the expression

I do not understand the output of the following program:

#include<stdio.h> int main() { int i=-3, j=2, k=0, m; m = ++i || ++j && ++k; printf("%d %d %d %d\n", i, j, k, m); return 0; } 

The output is -2 2 0 1 instead of -2 3 1 1 , implying that ++i was evaluated (and called the || operator to short-circuit its right side) before the expression ++j && ++k , which seems to contradict the fact that the && operator has a higher priority than || .

Can anyone explain why?

+6
c
source share
4 answers

Expression:

 ++i || ++j && ++k 

It is equivalent to:

 (++i) || ((++j) && (++k)) 

Clarification:

  • ++i is evaluated - (-2) || ((++j) && (++k)) (-2) || ((++j) && (++k)) ;
  • Operator || estimated - (1) ;

Since 1 || anything 1 || anything evalutes true, the right operand is not evaluated. So, the priority of && does not matter here. This short circuit is guaranteed both in C and C ++ by the relevant standards (see. Is there a short circuit of logical operators and evaluation procedure? ).

Now try using a subexpression, for example:

 (++i || ++j) && ++k 

Which is equivalent:

 ((++i) || (++j)) && (++k) 

Clarification:

  • ++i is evaluated - ((-2) || (++j)) && (++k) ;
  • || evaluated - (1) && (++k)
  • ++k evaluated - (1) && (1) ;
  • Computes true;
+2
source share

The result should look something like this:

 Error, line 2: 'm': undefined variable. 

Edit: with this fix, only ++i should be evaluated. Priority does not determine (or even affect) the evaluation order. Priority means that the expression is equivalent to ++i || (++j && ++k) ++i || (++j && ++k) . Evaluation Order for || or && always means that the left operand is evaluated and then there is a sequence point. After the sequence point, the right operand is evaluated if and only if it is necessary to determine the final result (i.e., the right operand || is evaluated if the left operand is evaluated to zero, the right operand && is evaluated if the left operand is evaluated as non-zero).

++i is evaluated in this expression, therefore, since it is the left operand || and is evaluated non-zero, none of the other expressions are evaluated.

+22
source share

-2 2 0 1

Lazy.

 #include <stdio.h> int main() { int i=-3,j=2,k=0; int m=++i||++j&&++k; printf("%d %d %d %d",i,j,k,m); } 

Compile, run and see for yourself.

 gcc tmp.c -o tmp 
+3
source share

As an explanation:

 #include <stdio.h> int main() { if (-1) printf ("-1!\n"); else printf ("Not -1.\n"); return 0; } 

Negative numbers are not false in C. Always compare booleans with 0 (or FALSE ) or you can bite if (worked == TRUE) false negatives.

0
source share

All Articles