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

Since the precedence of , operator is R-to-L, I expected the o/p to be 0, but on compiling the code is giving o/p as 1.

  • I don't understand you logic. How the R-to-L evaluation order (which is incorrect) is implying the `0` result you expect? – Eugene Sh. Jul 26 '19 at 16:11

1 Answers1

3

You've got a comma operator, so this is reasonably well defined. The subexpression

x++, x++

on the right-hand side means "add one to x and return x's old value, then add 1 to x and return x's old value." But the first "return value" gets thrown away, and the second part is what gets assigned to y, namely x's value after the first "add 1 to x" part, namely 1.

The comma operator always throws away the value computed by its left-hand side, and returns the value computed by its right-hand side.

Breaking it up even more explicitly, we have

y = (x++, x++);

     x++,            /* add 1 to x, giving 1, store 1 in x, return 0 (ignored) */
          x++        /* add 1 to x, giving 2, store 2 in x, return 1 */
y = (        );      /* so the 1 gets stored in y */

But notice that this has been well-defined only because of the sequence point that the comma operator gives you. For the comma operator and just one or two others, it's guaranteed that everything on the left-hand side (the computation of x + 1 and the store of this new value back into x) happen first, before anything on the right-hand side happens. But this is not true of most operators in C.

In particular, if we were to write the similar-looking expression

y = (x++ + x++);    /* WRONG, undefined */

there would be no sequence point, so there would be nothing to tell us what order the increments of x happened in, what values would get added together, what value would be assigned to y. See the canonical question Why are these constructs using pre and post-increment undefined behavior? for more on this kind of undefined expression.

Oh, and going back to your original question, you said

Since the precedence of , operator is R-to-L, I expected...

But this is wrong on several counts.

  • In this context, words like "right" and "left" generally refer to associativity, not precedence.
  • The associativity of the comma operator is left-to-right, not right-to-left.
  • The precedence of the comma operator is quite low (not that this matters).
  • Precedence and associativity don't actually help you understand evaluation-order puzzles like this at all.

On that last point: I'm not going to write another long essay on this topic here now (see the other question), but if you were trying to figure out the behavior of the undefined expression

y = x-- - x--;

by saying "okay, the associativity of the - operator is left-to-right, so we know that the left-hand x-- will get evaluated first, then the right-hand one", that would be a wrong conclusion, which would not lead to a correct prediction of the behavior of the expression.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Very well done. The language of the standard speaks in terms of the result of the postfix ++ operator being the value of the operand with the increment being applied as a "side effect", see [6.5.2.4 Postfix increment and decrement operators(p2)](http://port70.net/~nsz/c/c11/n1570.html#6.5.2.4p2) – David C. Rankin Jul 26 '19 at 19:35