7

I saw this in an exam and when I tried it out I was surprised. I tried it online and it works too. So I think it is the C language.

Why is that working? What is the use case for such an assignment syntax?

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    int i = (1,2,3,4,5);
    printf("%d", i);
    return 0;
}
Ely
  • 10,860
  • 4
  • 43
  • 64
  • 2
    The link is to some unrelated C++ program. Please update your question to show the output of your program. (It should be `5`.) – Keith Thompson Jul 30 '15 at 01:29
  • For what it's worth, there are languages which support multivalue expressions like 'r,theta = toPolar(x,y)'. But C and C++ don't. – keshlam Jul 30 '15 at 19:27
  • The link is just showing the online tool on which I tested it. The program shown initially is the site's default program. I only copy & pasted the displayed code of my question to test it there (I was doubting if my compiler maybe was being weird). – Ely Jul 30 '15 at 23:47

5 Answers5

10

These are not "multiple integers", but a comma operator. The whole parenthesised part is a single expression with each sub-expression (separated by commas) evaluated strictly from left to right. The results of all but the rightmost subexpression are ignored. The result of the whole expression is that of the last (rightmost) expression. Here it is the integer value 5.

Note that this operator is mostly used where only a single expression is allowed to add further side-effects. E.g. in a loop like:

int cnt = 0;
for ( const char *cp = "Hello" ; *cp != '\0' ; cp++, cnt++ )  ;

This counts the number of characters in a C-string, incrementing the pointer and cnt after each iteration. The results are ignored here.

So, this is in no way related to tuples or similar like in Python. There are actually no cases the usage of this operator is unavoidable and it should be used with caution — and some coding standards forbid its usage.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • 2
    In your example, only the second `,` is a comma operator, the first one is a comma separator. – M.M Jul 30 '15 at 04:02
  • @MattMcNabb: Right, thanks. I made a better example (well, as much as possible; i've got better ones, but they cannot easily be stripped down. – too honest for this site Jul 30 '15 at 11:38
  • Please refrain from answering off-topic questions. Your answer will inhibit the question to roomba and cause manual work to the community to delete. – old_timer Jul 25 '17 at 17:21
7

That's the comma operator at work. It evaluates the expression on its left-hand side, creates a sequence point, discards the value of the expression, then evaluates the expression on the right-hand side, and returns that as the value. When there are multiple expressions as in the example, then each is evaluated in turn and only the last is kept. With the sample, the compiler does the evaluation because every value is known at compile time. Note that the argument list to a function is not a use of the comma operator.

That isn't a valid use-case for the comma operator. What might be a more nearly valid use-case would be some operations with side-effects (such as function calls) that need to be sequenced and the final value assigned:

int i = (getchar(), getchar(), getchar());

This sets i to the third character in standard input, or EOF if there are not three characters left in the standard input to be read. Still not a realistic use-case, but better than assigning a list of constants.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    The comma operator is, in practice, one of the least useful parts of C/C++, since you can and should use separate statements for this kind of sequencing. – Kevin Jul 30 '15 at 01:45
  • 1
    @Kevin in C it's mostly useless, but in C++ as it can be overloaded, [sometimes it'll be useful](http://stackoverflow.com/q/5602112/995714) – phuclv Jul 30 '15 at 05:14
  • @Kevin In C++ the comma operator is extremely useful for template metaprogramming, actually. – Svalorzen Jul 30 '15 at 08:12
  • @Svalorzen: That's hardly the fault of the comma operator. TMP is a mess. – Kevin Jul 30 '15 at 11:57
3

In addition to the other answers, you need to watch for instances where a , is the comma operator as opposed to when it is a separator. For example, the following is invalid:

int i = 1,2,3,4,5;

In this case, the , is a separator between variable declarations. It declares i as an int and initializes it to 1, then it attempts to parse 2 as a variable name, which fails.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 3
    `2` is not a valid declaration, so the comma is neither a separator nor an operator in that code. The code is a syntax error because it doesn't match any syntax rule. – M.M Jul 30 '15 at 04:03
  • The code won't compile http://stackoverflow.com/q/17251584/995714 http://stackoverflow.com/q/20163411/995714 http://stackoverflow.com/q/8519884/995714 – phuclv Jul 30 '15 at 05:17
2

It works because you're using the "comma operator", which evaluates the subexpressions on the left and right, and has the value from the right-hand expression.

So in (1,2,3,4,5), 1 is evaluated and the result is discarded, then 2,3,4,5... in which (because of the next comma) 2 is evaluated and the result discarded, then 3,4,5... in which 3 is evaluated and discarded, then 4,5... in which 4 is evaluated and discarded, then 5 which becomes the result of the expression.

As for when it's useful, mainly as a shortcut when you need to evaluate several (sub)expressions for their side effects but aren't interested in their values (except maybe the last one). It's sometimes convenient in for loop expressions, such as when incrementing two variables:

for (i=0,j=1; j < len; i++,j++) {

..where it appears in both the initialization expression and the loop expression.

Dmitri
  • 9,175
  • 2
  • 27
  • 34
1

Why is that working?

Because its a valid C syntax. The comma in (1,2,3,4,5) are comma operator

C11: 6.5.17 Comma operator

Syntax
1 expression:

assignment-expression
expression , assignment-expression

Semantics
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.114)


What is the use case for such an assignment syntax?

See the example below

3 EXAMPLE As indicated by the syntax, the comma operator (as described in this subclause) cannot appear in contexts where a comma is used to separate items in a list (such as arguments to functions or lists of initializers). On the other hand, it can be used within a parenthesized expression or within the second expression of a conditional operator in such contexts. In the function call

f(a, (t=3, t+2), c)

the function has three arguments, the second of which has the value 5.

haccks
  • 104,019
  • 25
  • 176
  • 264