Categories
c comma-operator operators

What does the comma operator , do?

197

What does the , operator do in C?

3

  • possible duplicate of What is the proper use of the comma operator?

    – Sergey K.

    Aug 28, 2013 at 8:00

  • 1

    As I note in my answer, there is a sequence point after the evaluation of the left operand. This is unlike the comma in a function call which is just grammatical.

    Jun 25, 2014 at 11:46


  • 3

    @SergeyK. — Given that this was asked and answered years before the other, it is more likely that the other is a duplicate of this question. However, the other is also dual-tagged with both c and c++, which is a nuisance. This is a C-only Q&A, with decent answers.

    May 18, 2019 at 0:18

163

The expression:

(expression1,  expression2)

First expression1 is evaluated, then expression2 is evaluated, and the value of expression2 is returned for the whole expression.

6

  • 5

    then if I write i = (5,4,3,2,1,0) then ideally it should return 0, correct? but i is being assigned a value of 5? Can you please help me understand where am I going wrong?

    – Jayesh

    Nov 13, 2010 at 6:55

  • 22

    @James: The value of a comma operation will always be the value of the last expression. At no point will i have the values 5, 4, 3, 2 or 1. It is simply 0. It’s practically useless unless the expressions have side effects.

    Nov 13, 2010 at 7:06


  • 6

    Note that there is a full sequence point between the evaluation of the LHS of the comma expression and the evaluation of the RHS (see Shafik Yaghmour‘s answer for a quote from the C99 standard). This is an important property of the comma operator.

    Jun 20, 2014 at 20:47


  • 7

    i = b, c; is equivalent to (i = b), c because because assignment = has higher precedence than the comma operator ,. The comma operator has the lowest precedence of all.

    Feb 2, 2019 at 6:10

  • 1

    I worry that the parentheses are misleading on two counts: (1) they’re not necessary — the comma operator doesn’t have to be surrounded by parentheses; and (2) they could be confused with the parentheses around the argument list of a function call — but the comma in the argument list is not the comma operator. However, fixing it is not entirely trivial. Maybe: In the statement: expression1, expression2; first expression1 is evaluated, presumably for its side-effects (such as calling a function), then there is a sequence point, then expression2 is evaluated and the value returned…

    May 18, 2019 at 0:22

142

I’ve seen used most in while loops:

string s;
while(read_string(s), s.len() > 5)
{
   //do something
}

It will do the operation, then do a test based on a side-effect. The other way would be to do it like this:

string s;
read_string(s);
while(s.len() > 5)
{
   //do something
   read_string(s);
}

8

  • 28

    Hey, that’s nifty! I’ve often had to do unorthodox things in a loop to fix that problem.

    – staticsan

    Sep 4, 2009 at 1:47

  • 6

    Although it’d probably be less obscure and more readable if you did something like: while (read_string(s) && s.len() > 5). Obviously that wouldn’t work if read_string doesn’t have a return value (or doesn’t have a meaningful one). (Edit: Sorry, didn’t notice how old this post was.)

    – jamesdlin

    Mar 25, 2010 at 8:05


  • 14

    @staticsan Don’t be afraid to use while (1) with a break; statement in the body. Trying to force the break-out part of the code up into the while test or down into the do-while test, is often a waste of energy and makes the code harder to understand.

    – potrzebie

    Sep 27, 2012 at 6:20

  • 9

    @jamesdlin … and people still read it. If you have something useful to say, then say it. Forums have problems with resurrected threads because threads are usually sorted by date of last post. StackOverflow doesn’t have such problems.

    Nov 29, 2012 at 13:36

  • 4

    @potrzebie I like the comma approach much better than while(1) and break;

    – Michael

    Mar 11, 2016 at 14:19

44

The comma operator will evaluate the left operand, discard the result and then evaluate the right operand and that will be the result. The idiomatic use as noted in the link is when initializing the variables used in a for loop, and it gives the following example:

void rev(char *s, size_t len)
{
  char *first;
  for ( first = s, s += len - 1; s >= first; --s)
      /*^^^^^^^^^^^^^^^^^^^^^^^*/ 
      putchar(*s);
}

Otherwise there are not many great uses of the comma operator, although it is easy to abuse to generate code that is hard to read and maintain.

From the draft C99 standard the grammar is as follows:

expression:
  assignment-expression
  expression , assignment-expression

and paragraph 2 says:

The left operand of a comma operator is evaluated as a void expression; there is a sequence point after its evaluation. Then the right operand is evaluated; the result has its type and value. 97) If an attempt is made to modify the result of a comma operator or to access it after the next sequence point, the behavior is undefined.

Footnote 97 says:

A comma operator does not yield an lvalue.

which means you can not assign to the result of the comma operator.

It is important to note that the comma operator has the lowest precedence and therefore there are cases where using () can make a big difference, for example:

#include <stdio.h>

int main()
{
    int x, y ;

    x = 1, 2 ;
    y = (3,4) ;

    printf( "%d %d\n", x, y ) ;
}

will have the following output:

1 4

0