Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is comma operator free from side effect?

Tags:

c++

expression

For example for such statement:

c += 2, c -= 1

Is it true that c += 2 will be always evaluated first, and c in second expression c-= 1 will always be updated value from expression c += 2?

like image 491
scdmb Avatar asked Oct 16 '11 14:10

scdmb


4 Answers

Yes, it is guaranteed by the standard, as long as that comma is a non-overloaded comma operator. Quoting n3290 §5.18:

The comma operator groups left-to-right.

expression:
assignment-expression
expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded- value expression (Clause 5)83. Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field.

And the corresponding footnote:

83 However, an invocation of an overloaded comma operator is an ordinary function call; hence, the evaluations of its argument expressions are unsequenced relative to one another (see 1.9).

So this holds only for the non-overloaded comma operator.

The , between arguments to a function are not comma operators. This rule does not apply there either.

For C++03, the situation is similar:

The comma operator groups left-to-right.

expression:
assignment-expression
expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right and the value of the left expression is discarded. The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conver- sions are not applied to the left expression. All side effects (1.9) of the left expression, except for the destruction of temporaries (12.2), are performed before the evaluation of the right expression. The type and value of the result are the type and value of the right operand; the result is an lvalue if its right operand is.

Restrictions are the same though: does not apply to overloaded comma operators, or function argument lists.

like image 78
Mat Avatar answered Sep 20 '22 17:09

Mat


Yes, the comma operator guarantees that the statements are evaluated in left-to-right order, and the returned value is the evaluated rightmost statement.

Be aware, however, that the comma in some contexts is not the comma operator. For example, the above is not guaranteed for function argument lists.

like image 32
Blagovest Buyukliev Avatar answered Sep 24 '22 17:09

Blagovest Buyukliev


Yes, in C++ the comma operator is a sequence point and those expression will be evaluated in the order they are written. See 5.18 in the current working draft:

[snip] is evaluated left-to-right. [snip]

I feel that your question is lacking some explanation as to what you mean by "side effects". Every statement in C++ is allowed to have a side effect and so is an overloaded comma operator.

Why is the statement you have written not valid in a function call?

It's all about sequence points. In C++ and C it is forbidden to modify a value twice inside between two sequence points. If your example truly uses operator, every self-assignment is inside its own sequence point. If you use it like this foo(c += 2, c -= 2) the order of evaluation is undefined. I'm actually unsure if the second case is undefined behaviour as I do not know if an argument list is one or many sequence points. I ought to ask a question about this.

like image 42
pmr Avatar answered Sep 22 '22 17:09

pmr


It should be always evaluated from left to right, as this is the in the definition of the comma operator: Link

like image 22
tune2fs Avatar answered Sep 24 '22 17:09

tune2fs