S.C.
S.C.

Reputation: 231

Nuances of comma seperator and comma operator when used in initialization and declaration statements

I was playing around with the , operator after reading several of the answers on a Stack Overflow post (What does the comma operator , do?). Further, I was playing around with the , separator after reading this post: comma operator and comma seperator in c++. Consider the following two code snippets:

Code 1

#include<stdio.h>
int main(void) 
{
  int a, b;      /* comma functions as a separator */
  a = 5, b=9;    /* NOT SURE how comma functions */
  printf("a = %d \n",a) , printf("b = %d \n",b);     /* comma functions as an operator */      
}

Code 2

#include<stdio.h>
int main(void) 
{
  int a, int b;   /* not allowed - compiler error ... NOT SURE how comma functions */
  a = 5, b=9;     /*NOT SURE how comma functions */
  printf("a = %d \n",a) , printf("b = %d \n",b);      /*comma functions as an operator */      
}

The top code (Code 1) is fine...and prints out a=5 and b=9; however, the bottom code (Code 2) does not make it past the compiler and cites the int a, int b ; line as the incriminating action.


There are a lot of questions bundled up in these two code snippets but I'll bullet out the ones I care about the most:

  1. In the statement a=5,b=9; is that , functioning as a separator or an operator? I've read that in initialization statements, commas function as separators. However, given my understanding of what a comma operator would do, I feel like classifying this comma as an operator makes sense as well.

  2. Why is int a, int b not allowed? If the comma was allowed to behave as an operator, then certainly this would make sense, right? int a would be evaluated first and it would have the side effect of labeling some place in memory with the identifier of a and then int b would be processed in a similar way. Therefore, it seems as though the compiler does not want to alter the interpretation of the , in this case (i.e. it only ever wants to think of it as a separator).

An explanation would be greatly appreciated! Thanks~

Upvotes: 1

Views: 118

Answers (3)

John Bollinger
John Bollinger

Reputation: 180161

  1. In the statement a=5,b=9; is that , functioning as a separator or an operator?

It is an operator.

I've read that in initialization statements, commas function as separators. However, given my understanding of what a comma operator would do, I feel like classifying this comma as an operator makes sense as well.

There is no such thing as an "initialization statement". Initialization, in the sense you must have been reading about, is something that can be expressed as part of a declaration of an object. Assignment, even the first assignment to an uninitialized variable, is not initialization in that sense. Syntactic similarity notwithstanding.

  1. Why is int a, int b not allowed?

Ultimately, because the language designers decided it shouldn't be. However, ...

If the comma was allowed to behave as an operator, then certainly this would make sense, right?

No, not particularly. For , to function as an operator there, int a and int b would need to be expressions, serving as its operands. They are not. Rather, they are each most of a declaration. Among the distinctions is that declarations do not evaluate to values.

int a would be evaluated first and it would have the side effect of labeling some place in memory with the identifier of a and then int b would be processed in a similar way.

Perhaps in some other language it could work that way. In C, it does not.

Therefore, it seems as though the compiler does not want to alter the interpretation of the , in this case (i.e. it only ever wants to think of it as a separator).

The comma-as-separator is part of the C syntax for declarations (among other things). The comma-as-operator is part of the C syntax for expressions. If it confuses you or otherwise you dislike it then you can avoid comma-as-separator in declarations: instead, write

int a;
int b;

Some C style guides demand that, in fact, instead of declaring multiple variables in the same statement.

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

The declaration in C is defined (in particularly) like

declaration:
    declaration-specifiers init-declarator-list ; 

where the term init-declarator-list is defined like

init-declarator-list:
    init-declarator
    init-declarator-list , init-declarator

So in the first program in this declaration

int a, b;

there is no comma operator. The comma is used to separate init-declarators in the init-declarator-list.

This statement

a = 5, b=9; 

is indeed a statement with the comma operator expression.

This statement

printf("a = %d \n",a) , printf("b = %d \n",b);

is also a statement with the comma operator expression.

This declaration in the second program is incorrect

int a, int b; 

because the declaration specifier int is used inside the init-declarator-list.

As for the comma operator then according to the C Standard (6.5.17 Comma operator)

2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value

You can use the comma operator as an initializer of a variable for example like

int a = 10, b = 20;
int c = ( a++, b++, a + b );

The variable c will be initialized by the value 32.

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    int a = 10, b = 20;
    
    printf( "a = %d, b = %d\n", a, b );
    
    int c = ( a++, b++, a + b );

    printf( "a = %d, b = %d, c = %d\n", a, b, c );

    return 0;
}

Its output is

a = 10, b = 20
a = 11, b = 21, c = 32

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 222427

  1. In the statement a=5,b=9; is that , functioning as a separator or an operator?

The comma here is an operator. In the C grammar:

  • This is a statement that is an expression-statement (C 2018 6.8).
  • It consists of an expression followed by a ; (6.8.3).
  • An expression may be an expression followed by a , and then an assignment-expression (6.5.17).
  • That expression before the comma may also be an assignment-expression (6.5.17).

So a=5,b=9; is “assignment-expression , assignment-expression ;”.

Note that a=5 is not an “initialization statement”; there is no such thing in the C grammar. It is an assignment-expression. So a=5,b=9; is two assignment expressions joined by a comma and terminated with a semicolon, which forms a single statement.

  1. Why is int a, int b not allowed?

In the C grammar:

  • This is a declaration (6.7).
  • It consists of declaration-specifiers followed by an init-declarator-list followed by a ; (6.7).
  • The declaration-specifiers may be a single type-specifier (6.7) which is int (6.7.2).
  • The init-declarator-list is a list of init-declarator separated by commas (6.7).
  • An init-declarator may be a declarator (6.7).
  • A declarator may be an identifier, like a or b (6.7.6).

So int a, b; is a valid declaration. There is no provision in the C grammar for anything that is a list of declarations separated by commas; nothing in the grammar lets anything expand to “declaration , declaration”.

In int a, b;, we can have a list of identifiers separated by commas because the grammar for init-declarator-list allows that.

(The init-declarator items in an init-declarator-list can also be “declarator = initializer”, which is how you can have initializations in a declaration.)

Upvotes: 1

Related Questions