Comma expressions

A comma expression contains two operands of any type separated by a comma and has left-to-right associativity. The left operand is fully evaluated, possibly producing side effects, and its value, if there is one, is discarded. The right operand is then evaluated. The type and value of the result of a comma expression are those of its right operand, after the usual unary conversions.

C only

The result of a comma expression is not an lvalue.

End of C only
C++ only

In C++, the result is an lvalue if the right operand is an lvalue. The following statements are equivalent:

r = (a,b,...,c);
a; b; r = c; 

The difference is that the comma operator may be suitable for expression contexts, such as loop control expressions.

Similarly, the address of a compound expression can be taken if the right operand is an lvalue.

&(a, b)
a, &b
End of C++ only

Any number of expressions separated by commas can form a single expression because the comma operator is associative. The use of the comma operator guarantees that the subexpressions will be evaluated in left-to-right order, and the value of the last becomes the value of the entire expression. In the following example, if omega has the value 11, the expression increments delta and assigns the value 3 to alpha:

alpha = (delta++, omega % 4);

A sequence point occurs after the evaluation of the first operand. The value of delta is discarded. Similarly, in the following example, the value of the expression:

intensity++, shade * increment, rotate(direction);

is the value of the expression:

rotate(direction)

In some contexts where the comma character is used, parentheses are required to avoid ambiguity. For example, the function

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

has only three arguments: the value of a, the value 5, and the value of c. Other contexts in which parentheses are required are in field-length expressions in structure and union declarator lists, enumeration value expressions in enumeration declarator lists, and initialization expressions in declarations and initializers.

In the previous example, the comma is used to separate the argument expressions in a function invocation. In this context, its use does not guarantee the order of evaluation (left to right) of the function arguments.

The primary use of the comma operator is to produce side effects in the following situations:

The following table gives some examples of the uses of the comma operator.

Statement Effects
for (i=0; i<2; ++i, f() ); A for statement in which i is incremented and f() is called at each iteration.
if ( f(), ++i, i>1 ) { /* ... */ } An if statement in which function f() is called, variable i is incremented, and variable i is tested against a value. The first two expressions within this comma expression are evaluated before the expression i>1. Regardless of the results of the first two expressions, the third is evaluated and its result determines whether the if statement is processed.
func( ( ++a, f(a) ) ); A function call to func() in which a is incremented, the resulting value is passed to a function f(), and the return value of f() is passed to func(). The function func() is passed only a single argument, because the comma expression is enclosed in parentheses within the function argument list.