-7
  #include <stdio.h>
 //Compiler version gcc 6.3.0

 int main(void)
 {
    int i=10, j=2, k=0, m;
    m=++i || ++j && ++k;
    printf("%d,%d,%d,%d",i,j,k,m);
 }

can anyone explain the logic, Output is 11,2,0,1

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 2
    Have you tried going through it on paper? Do you know about "short-circuit evaluation"? – UnholySheep Oct 06 '17 at 13:34
  • 1
    Possible duplicate of [Undefined behavior and sequence points](https://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – Caleb Oct 06 '17 at 13:34
  • 2
    @Caleb not at all, everything here is sequenced and well-defined. – Quentin Oct 06 '17 at 13:46
  • 1
    @Caleb This code is well-defined and there is no issue with UB or sequence points. – Lundin Oct 06 '17 at 13:52

2 Answers2

2

Due to the priorities of operations this expression statement

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

is equivalent to

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

You can imagine it like

m = expression1 || expression2;

where expression1 is ++i and expression2 is ( ++j && ++k )

According to the C Standard (6.5.14 Logical OR operator)

4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

As expression1 compares unequal to 0 (its value is equal to 11) then expression2 is not evaluated.

Thus only expression1 is evaluated and it is unequal to 0.

According to another quote from the same section of the C Standard

3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

The result of the evaluation of the right side is equal to 1 that is assigned to the variable m.

Thus only the variable i and m were changed. The variables j and k were not changed because the expression where they are present as operands was not evaluated.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

i starts as 10, but is incremented to 11, before it is tested.

m is being assigned a boolean result, so will be either 0 or 1.

i is non zero so evaluates to true for a boolean expression, therefore, the expression after the || do not need to be evaluated, as || is a boolean short circuit evaluator.

Hence your output.

Dragonthoughts
  • 2,180
  • 8
  • 25
  • 28