1

If the associativity of the comma operator is from left to right, then why does the first printf execute the second argument expression first, rather than first argument?

#include "stdio.h"

int main()
{
 int a = 10;
 int b = 15;

 printf("=%d",a=a+1,b=a+2);
 printf(" %d=",b);

 return 0;
}
Jonathan Leffler
  • 698,132
  • 130
  • 858
  • 1,229
Mahantesh
  • 55
  • 6
  • 4
    The comma in your example is separating the function call's arguments and they may be evaluated in any sequence. This is quite different from the comma in the statement `a=a+1,b=a+2;` – Weather Vane Apr 20 '17 at 14:09
  • 7
    There is no comma _operator_ in the code shown. There are only commas used to separate arguments in function calls, which are emphatically ***not*** comma operators. The code shown has undefined behaviour; the value of `a` is both modified and used between sequence points. – Jonathan Leffler Apr 20 '17 at 14:15
  • You mean to say that in the above line comma acts as a separator and the rightmost value is assigned to the variable and when I use it as ("=%d",(a=a+1,b=a+2)),it acts as operator and evaluates the most leftside till the last right side operand? Am I right? @JonathanLeffler – Mahantesh Apr 20 '17 at 14:20
  • Basically yes. With the extra parentheses, the comma enclosed becomes a comma operator and everything becomes well-formed — no undefined behaviour. Without the extra parentheses, there is no comma operator, just 'comma separators', and it is undefined how the two argument expressions are evaluated — and because `a` is used in both expressions, once as the target of an assignment and once as the source of a value, the behaviour is undefined because there is no sequence point between the evaluation of the arguments. This is mostly nit-picking nuance — what you say is OK to a first approximation. – Jonathan Leffler Apr 20 '17 at 14:30
  • In the expression ` printf("=%d",(a=a+1,b=a+2))` you have the parenthesis operator `(a= ... +2)`, which has higher precedence than the function call operator `printf(...)`, meaning that the contents of the parenthesis will get translated (but not necessarily executed) before the things outside it. – Lundin Apr 20 '17 at 14:36
  • Please stop writing code that in any way resembles this. – ThingyWotsit Apr 20 '17 at 15:01

2 Answers2

3

In your example the code printf("=%d",a=a+1,b=a+2); uses comma to separate function arguments and the compiler is free to chose which gets evaluated first.

The reason the last parameter (in this case) is evaluated first is implementation-dependent and is likely to do with the fact that this argument is put on stack first, followed by the second argument, followed by the first one (this is the reason the printf() can have variable number of arguments - those are being pushed onto stack, beginning with the "tail").

If you really want to enforce the precedence - use the parenthesis, like this:

 printf("=%d", (a=a+1,b=a+2) );

This will make sure the comma operator is done first, and the argument evaluation comes after it

YePhIcK
  • 5,716
  • 2
  • 23
  • 47
  • Thanks @YePhIcK, You conclude the order is complier dependent? – Mahantesh Apr 20 '17 at 14:27
  • The standard leaves this up to specific implementations, but in practice this is the *usual* way of doing it. Precisely because of the (this *is* standard) promise that the last argument is being put on the stack first – YePhIcK Apr 20 '17 at 14:29
3
printf("=%d",a=a+1,b=a+2);

The comma here is not the comma operator, but an argument list, part of the function call syntax.

The order of evaluation of function parameters is unspecified behavior, meaning that the compiler may evaluate the left or the right parameters first, and you cannot know which.

In addition, your code contains a side-effect of updating the variable a=a+1. This is written in the same expression as code that uses a for other purposes than to determine which value to store in a, namely b=a+2. These two sub-expressions are not sequenced in relation to each other, so your code invokes undefined behavior. Meaning this is a bug and anything can happen.

And since you only have one format specifier in printf, but pass 2 arguments, you invoke a different kind of undefined behavior there too, likely resulting in a crash, or if you are lucky, a compiler message.

Lundin
  • 174,148
  • 38
  • 234
  • 367