2
#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;
}

why is the output giving result -2 2 0 1?

one logic is ( ++j&& ++k) is not computed as ++i is non zero

but as && has higher preference than || why they are not computed

simonc
  • 41,632
  • 12
  • 85
  • 103
user1495306
  • 121
  • 1
  • 6

4 Answers4

5

Precedence does not specify the order in which an expression is evaluated. It specifies how an expression is interpreted. In this case, the precedence rules of C (which are embedded in its formal grammar) cause a || b && c to be interpreted as a || (b && c).

When this expression is evaluated, the rules of C specify that a must be evaluated first. The rules also state that if a is true, then value of the entire expression is true, and the right side of the || is not evaluated.

To see this more clearly, consider the expression a + b < c * d. The precedence rules cause this to be interpreted as (a + b) < (c * d). However, unlike ||, the rules of C do not specify that the left side of < must be evaluated first. The compiler may evaluate a + b first or c * d first, even though * has higher precedence than +. The compiler is allowed to use any evaluation order that gets the right answer.

The only order imposed here is that a + b and c * d must both be evaluated before the < can be evaluated. However, that comes from the structure of the expression, not the rules of precedence.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
4

Operators && and || computation order is left-to-right. Compiler guarantees that operator's || right operand will not be computed if left operand evaluates to true.

  • 1
    It should be the language to establish the guarantee. – A. K. Jan 10 '13 at 15:11
  • but as && has higher prefernce than || shouldn't the expression involving && should be evaluated first. – user1495306 Jan 10 '13 at 15:12
  • 1
    @user1495306: precedence affects grouping; it doesn't affect order of evaluation. `||` and `&&` guarantee left-to-right evaluation, period. The expression `++i || ++j && ++k` is interpreted as "the result of the expression `++i` OR the result of the expression `++j && ++k`." `++i` is evaluated first; `++j && ++k` will only be evaluated if the result of `++i` is 0. – John Bode Jan 10 '13 at 15:31
1

m = ++i || ++j && ++k;

++i will executes first. Since, i will become -2 ,which means/equivalent to true. It won't execute ++j && ++k part and m value will be 1.

So, final output will become -2 2 0 1

When executing ||, it will executes the left hand part first and if it true then it won't proceed to right. Since, it is not going matter, whether right-part is true or false. So, in you case, left part of || executed and since it return non-zero value that means true.

Ravi
  • 30,829
  • 42
  • 119
  • 173
  • but why? as && has more prefernce than || shouldn't the expression (++j && ++k) be evaluated first – user1495306 Jan 10 '13 at 15:09
  • please read my answer, as i said it will start execution from `++i`. – Ravi Jan 10 '13 at 15:14
  • 1
    @user No. Precedence just changes which operators are applied to which operands, it doesn't necessarily have anything to do with the order of execution. As || is defined as not evaluating it's second operand if the first evaluates to true, it can't evaluate (++j && ++k). – Cubic Jan 10 '13 at 15:15
1

Due to short circuit evaluation

m = ++i || ++j && ++k;

is equivalent to

++i;
m = i != 0;
if(!m) {
  ++j;
  m = j != 0;
  if(m) {
    ++k;
    m = k != 0;
  }
}
Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48