Comma operator ,
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.
The result of a comma expression is not an lvalue.
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
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:
- Calling a function
- Entering or repeating an iteration loop
- Testing a condition
- Other situations where a side effect is required but the result of the expression is not immediately needed
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. |