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

this actually assigns 1 to i.

*****I wonder if this type of assignment is actually useful somewhere?*****

Do you know some application of this syntax?

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
Moeb
  • 10,527
  • 31
  • 84
  • 110

9 Answers9

15

This syntax is really useful when you want to have say 2 iteration variables in a for loop

for ( i = 0, j = 0; i < 10 && j < 10; i++ ) {
  ..
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
14

It's the comma operator, C's lowest precedence operator. According to C's precedence rules, that line parses as this:

(i = 1), (2), (3), (4), (5);

This could be "useful" if you wanted to do something else on that line:

i = 2, j = 3, k++;

Could save you from using brackets for an if() statement (and could also induce headaches later) or allow you to have multiple expressions in a for() loop's control flow (which is actually a pretty legitimate use of the comma operator).

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
  • Yes. The only thing to add is that the comma is also often used to put multiple declarations of the same type on the same line: int i, j, cookies=7, width, height; – Benji XVI Nov 05 '09 at 23:42
  • 2
    @Benji - that's one of things that's confusing about an already confusing comma operator. Those commas aren't operators; they're separators required by the C grammar for multiple declarators in an init-declarator-list. Other commas which aren't operators include the ones that separate function parameters/arguments and the ones that separate enums when they're being defined. There are probably others. – Michael Burr Nov 06 '09 at 01:13
6

Application: the Obfuscated C Contest!

Anton
  • 3,170
  • 20
  • 20
6

Another common use for the comma operator is in while loop conditions:

while (c = getchar(), c != EOF && c != '\n')
{
caf
  • 233,326
  • 40
  • 323
  • 462
  • `getchar` returns EOF on any error, the error handling code would thus be after the loop. – caf Nov 05 '09 at 23:19
5

It's not a "type of assignment". The comma operator binds very loosely, looser than assignment. So you've written the equivalent of:

((((i = 1), 2), 3), 4), 5;

Integer literals in void contexts are useless (except maybe for avoiding warnings in macros that do nothing in certain cases, like assert), so no, there's no use for exactly this syntax - the need for an expression which sets i to 1 and evaluates to 5 is pretty limited, and even if you found a case for that, the 2,3,4 are redundant.

More useful could be i = 1, code_that_actually_does_something;. The most frequent use of the comma operator is to sneak in multiple side-effects in a context where you're not allowed multiple statements, such as in "if" and "while" conditions, or macros that have to evaluate as expressions.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
3

This is the comma operator, which allows you to combine multiple expressions into one.

The compiler parses it as (i = 1), 2, 3, 4, 5, because = has a higher priority than the comma operator.

Except in for loops, it is not generally useful and its use is frowned upon.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

In an assignment, I can't think of where this particular example would be useful.

You can, however, do

x = 1, y = 2, z = 3;

And they'll be treated as a single statement, and evaluated from left-to-right (according to C89).

user47559
  • 1,201
  • 8
  • 9
0

As the others already pointed out: This statement assigns 1 to i, then evaluates 2, then 3, then 4 and then 5. The overall value of the statement is then 5 (the last evaluated expression).

swegi
  • 4,046
  • 1
  • 26
  • 45
0

This is useful when you want to create a macro that does several things and returns a value like a function:

#define STEAL_MAGIC_HAT(thing1, thing2, cat) \
(smack(thing1), punch(thing2),get_hat(cat))

extern thing_t g_thing1, g_thing2;
extern cat_t g_cat;
...

    hat_t hat = STEAL_MAGIC_HAT(g_thing1, g_thing2, g_cat);
    don(hat);
...
Tim Schaeffer
  • 2,616
  • 1
  • 16
  • 20