8

So I came across this question somewhere:

Case 1:

int a;
a = 1, 2, 3;
printf("%d", a);

Case 2:

 int a = 1, 2, 3;
 printf("%d", a);

The explanation says:

The second case gives error because comma is used as a separator, In first case = takes precedence over , so it is basically (a=1), 2, 3;

But I want to ask why does = not take precedence over , in Case 2?

code707
  • 1,663
  • 1
  • 8
  • 20
Rahul Ranjan
  • 135
  • 1
  • 8

4 Answers4

10

It is not just a question of precedence, but rather a question of the language grammar: the = in both cases is not the same operator:

  • in the declaration int a = 1, 2, 3;, the = token introduces an initializer which cannot be a comma expression. The , ends the initializer and the compiler issues an error because 2 is not a valid identifier for another variable.

  • in the statement a = 1, 2, 3;, a = 1, 2, 3 is an expression, parsed as ((a = 1), 2), 3 because = has higher precedence than ,. = is the assignment operator whose right hand side is an expression, this assignment is the left operand of a comma operator , followed by a constant expression 2, a = 1, 2 itself the left operand of the final , operator whose right operand is 3. The statement is equivalent to ((a = 1), 2), 3);, which simplifies into a = 1;.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    In particular, the `=` token introduces an *assignment-expression*, which is defined in C 2011 6.5.16, which can be any of the prior types of expression (*conditional-expression*, *logical-OR-expression*, and so on) but cannot be an *expression*, which comes later, in 6.5.17. – Eric Postpischil Jul 01 '18 at 12:45
  • 1
    However, the statement that the right-hand side of an assignment expression can be a comma expression is incorrect. The right-hand side of an *assignment-expression* is an *assignment-expression*. In `a = 1, 2, 3;`, the text is parsed as `((a = 1), 2), 3;`. What is actually happening here is that `a = 1, 2, 3;` is a *statement*, in particular an *expression-statement*, in which `a = 1, 2, 3` is an *expression*, which can be “*expression*, *assignment-expression*”. – Eric Postpischil Jul 01 '18 at 12:47
7

This

int a = 1, 2, 3;/* not a valid one */

is wrong because since = has higher priority, so it become int a = 1 internally and there is no name for 2 and 3 thats why this statement is not valid and cause compile time error.

To avoid this you might want to use

int a = (1, 2, 3); /* evaluate all expression inside () from L->R and assign right most expression to a i.e a=3*/

And here

int a;
a = 1,2,3; 

there are two operator = and , and see man operator. The assignment operator = has higher priority than comma operator. So it becomes a=1.

a = 1,2,3;
    | L--->R(coma operator associativity) 
    this got assigned to a

for e.g

int x = 10, y = 20,z;
z = 100,200,y=30,0; /* solve all expression form L to R, but finally it becomes z=100*/ 
printf("x = %d y = %d z = %d\n",x,y,z);/* x = 10, y = 30(not 20) z = 100 */
z = (100,200,y=30,0); /* solve all expression form L to R, but assign right most expression value to z*/ 
Achal
  • 11,821
  • 2
  • 15
  • 37
5

Inside variable declarations (as case 1) comma are used to declare several variables, for example:

int a,b=2,c=b+1,d; //here only b and c were initialized

An statement in C/C++ could be a list of comma separated expressions (this is what happens in case 2):

a=b+1, c+=2, b++, d = a+b+c, 3, d; //these are expressions, remember one literal is an expression too!!!
Eduardo Pascual Aseff
  • 1,149
  • 2
  • 13
  • 26
3

NOTE : comma (,) is a compile time operator,
from my side their is Four cases that you can come across :
case 1

int a = 1, 2, 3; // invalid case cause too many initializers

case 2

int a = (1, 2, 3); // valid case
/* You can expand this line as a :
   1;
   2;
   int a = 3;
*/

case 3

int a;
a = 1, 2, 3; // valid case
/* You can expand this line as a : 
   a = 1; // expression 1
   2;     // expression 2            
   3;     // expression 3
*/

case 4

int a;
a = ( 1, 2, 3);// valid case
/* You can expand this line as a :
   1;     // expression 1
   2;     // expression 2
   a = 3; // expression 3
*/  

In above cases in place of 1, 2, 3 we can use any valid expression in C, explore more!!

Jeet Parikh
  • 305
  • 2
  • 8