0

Both the comma operator and the semicolon can be used to separate statements. Let's consider this simple code:

#include <stdio.h>

void do_something(int*i) {(*i)++;}

int main() {
    int i;
    scanf("%d", &i),
    i++,
    do_something((i++, &i)),
    printf("i is now %d\n", i);
    if(i == 5) printf("MAGIC NUMBER\n");
    return 0;
}

I've been experimenting when can I use the comma instead of the semicolon. It turns out that the semicolon is mandatory after int i and before return and if; and, of course, after the closing brace.

Why can't we have only one statement separating facility? Why weren't the comma and the semicolon be blended? Their use seems to greatly overlap, only that in some contexts (like before keywords) we can only use the semicolon, while in some other contexts (like in the while loop condition or in a function argument) we can only use the comma.

  • 6
    I don't know C, but isn't the comma operator used to separate (or actually rather combine) expressions not statements? – Jörg W Mittag Mar 30 '18 at 22:06
  • 1
    Isn't that then a statement expression, which is an expression and not a statement? Uh. That makes my head hurt. C is weird. But like I said: I don't know C. (Not to be confused with an expression statement, which is a statement and not an expression, and totally different from a statement expression, which is an expression and not a statement.) – Jörg W Mittag Mar 30 '18 at 22:19
  • 3
    This is a duplicate question: stackoverflow.com/questions/2087026/… – Robert Baron Mar 30 '18 at 22:22
  • 1
    This is one of those cases where a little self-discipline goes a long way. Just because you can do a thing, doesn't mean that you should do that thing. – Robert Harvey Mar 30 '18 at 22:46
  • 1
    its an odd question, but the answer is pretty interesting and gives insight into language design – Ewan Mar 31 '18 at 9:04
5

You are generally right that the comma operator and the semicolon are very similar and both serve as a sequence point. In some languages, there is only a single operator that serves both purposes.

However, the C syntax is statement-oriented. Statements and Expressions play very different roles in its grammar. So while a semicolon is used to separate statements, the comma operator can be used to separate expressions. This has the advantage of making the syntax a bit more robust. E.g. this is clearly a syntax error:

foo(f();
g());

whereas foo((f(), g())) is valid, but usually bad style.

In expression-oriented languages, there are no or fewer statement-level syntax constructs. In these languages, there may not be a comma operator. E.g. in Rust, it is possible to embed statements in an expression, like

foo({ f(); g() });

Here, a comma operator is no longer necessary. Note that the GCC compiler offers a similar syntax extension for C and C++. In standard C++11, you can get similar syntax through an immediately invoked lambda:

foo([]{ f(); return g(); }());
|improve this answer|||||
3

Comma operator in C works as both an operator and a separator.While working with declaration and function calls,comma operator works as a separator.

In your case,technically it works as an operator.Each of the statement you have written separated by ',' is an expression in itself.

A statement like

(expression 1,expression 2,.......,expression n)

evaluates all the expressions and returns the value of expression n. That is why you cannot use it after 'int i' or before 'return' or 'if' since these all are statements and not expressions.

You are allowed to do this

int i;
i,
scanf("%d", &i),
i++,
do_something((i++, &i)),
printf("i is now %d\n", i);
if(i == 5) printf("MAGIC NUMBER\n");
return 0;

because just writing the variable name returns its value.

In your code all the statements separated by ',' are evaluated and the value returned is the one which printf() function returns(i.e the number of characters printed)

Try this

int i;
int val=(
scanf("%d", &i),
i++,
do_something((i++, &i)),
printf("i is now %d\n", i));
if(i == 5) printf("MAGIC NUMBER\n");
printf("%d",val);
return 0;

With input as 1 ,i becomes 4 and the output is

i is now 4
11

since the string "i is now 4\n" contains 11 characters

|improve this answer|||||
  • (expression 1,expression 2,.......,expression n) is an expression, not just a statement. Of course every expression is also a statement – Basile Starynkevitch Jun 17 '18 at 8:12
  • @BasileStarynkevitch ... if you add a semicolon. – gnasher729 Jun 17 '18 at 14:17
  • 1
    No, the semicolon is separating statements, not part of them. – Basile Starynkevitch Jun 17 '18 at 14:48
1

C has two different notions: expressions and statements. Check by reading some C standard like n1570. Notice that expressions are statements, but some statements (e.g. while, switch, goto ...) are not expressions.

Some languages (such as Ocaml, Scheme, Lisp, ....) have only expressions (and don't have any kind of statements). In such languages the sequence needs only one construct. Notice for example that in Ocaml, its ; is like C comma operator, and that in Scheme begin is for sequence constructions (but accepts many operands). Of course you should read SICP if you didn't yet.

The comma operator is making (like the ternary conditional operator, or the binary +) a composite expression (made of operands, which are simpler sub-expressions).

The semi-colon separates two statements inside statement sequences (which appear in blocks). Of course you could (but this is not readable) separate expressions by commas to make them a statement; but you could (and this is more readable) make a sequence of expression statements.

Both the comma operator and the semicolon can be used to separate statements.

This is wrong: while(i<10) {i++;}, i is not a valid C statement -but both left and right of , are valid statements (the right one, i, being an expression statement). The GCC and Clang compilers accept as an extension statement expressions (for some reason, that useful feature exists since more than a dozen of years but has not been standardized).

(I am not sure of that, but I heard that B, the ancestor of C, had just expressions; so its while "statement" evaluated into -1 when used as an expression; I could be wrong ....)

I would prefer C to have only expressions, with some of them (like while) being of void type. But this is not how the programming language evolved and is now defined. I would also prefer statement expressions and computed goto-s (and some other extensions provided by GCC) to be part of the C standard. I don't know why it is not so! Part of the reason is that being member of the C standardization committee is a lot of work (nearly a full time job) and lobbying and costs a lot -notably in travels- (and I guess that GCC folks had not enough money for that, when -in the previous century- they introduced their C extensions).

BTW, after reading the Dragon Book and studying deeply the C11 standard, you might design a C-like language which has only expressions (that is, which mixes statements into expressions like I wish C did) and implement it in your toy compiler (using some existing code generation library like libgccjit or LLVM or compiling it into C). That could make an interesting semester student project (at master's level). Look into academic languages like Terra or Cyclone for inspiration. You could also quite easily (semester of work) patch GCC or Clang to add a new construct: -let call it "the void statement expression"- where void followed by some simple non-expression statement or block is a new valid expression of type void (so void while(i<10) {i++;}, i would be a valid expression). Having that extension accepted by the GCC or Clang community is a different story (today, both GCC and Clang communities are unfriendly to new language extensions).

|improve this answer|||||
0

The comma operator doesn't separate statements at all. It combines multiple expressions into a larger expression: expr1, expr2 evalutes expr1, followed by a sequence point, then evaluates expr2.

But your question is "why": It's because 40 years ago, that kind of shortcut was considered a clever and useful idea. 40 years later, ideas what is clever and useful have changed a lot.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.