Turn Turn - 4 months ago 18
C Question

Why is gcc not treating comma as a sequence point?

I'm observing different behavior regarding what I think is part of the C standard between

(either the homebrew version on my mac or on linux). The question is whether the comma in an argument list is a sequence point or not.
interprets it as such but
does not.

This code demonstrates the issue:

#include <stdio.h>

int inner(int *v) {
*v += 1;
return 1;

int outer(int x, int y) {
return y;

int main(int argc, char *argv[]) {
int x = 4;
printf ("result=%d\n", outer(inner(&x), x));

And the results:

$ clang -o comseq comseq.c && ./comseq
$ gcc-4.8 -o comseq comseq.c && ./comseq
$ gcc-5 -o comseq comseq.c && ./comseq

I don't have access to a copy of the C standard at the moment, but I was pretty sure that
's behavior was correct until I saw
's interpretation. Playing with the
option didn't change my results at all.


On a better reading it is true that this question is answered in http://stackoverflow.com/a/4176333/3171657:

a , b (§5.18) (in func(a,a++) , is not a comma operator, it's merely a separator between the arguments a and a++. The behaviour is undefined in that case if a is considered to be a primitive type)

but that, while very useful, is a long answer so maybe leaving this question around will help other users like myself. Also, to be pedantic, that question is about C++, not C.


Commas in argument lists are not sequence points — they are not comma operators within the meaning of the term.

The section of the standard (ISO/IEC 9899:2011) on function calls (§ says:

¶3 A postfix expression followed by parentheses () containing a possibly empty, comma- separated list of expressions is a function call. The postfix expression denotes the called function. The list of expressions specifies the arguments to the function.

¶4 An argument may be an expression of any complete object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.

¶10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

(I've omitted a couple of footnotes, but the contents are not germane to the discussion.)

There is nothing about the expressions being evaluated in any particular sequence.

Note, too, that a comma operator yields a single value. If you interpreted:

function(x, y)

as having a comma operator, the function would have only one argument — the value of y. This isn't the way functions work, of course. If you want a comma operator there, you have to use extra parentheses:

function((x, y))

Now function() is called with a single value, which it the value of y, but that is evaluated after x is evaluated. Such notation is seldom used, not least because it is likely to confuse people.