What's the result of += in C and C++?

C++C

C++ Problem Overview


I've got the following code:

#include <stdio.h>
int main(int argc, char **argv) {
    int i = 0;
    (i+=10)+=10;
    printf("i = %d\n", i);
    return 0;
}

If I try to compile it as a C source using gcc I get an error:

error: lvalue required as left operand of assignment

But if I compile it as a C++ source using g++ I get no error and when i run the executable:

i = 20

Why the different behavior?

C++ Solutions


Solution 1 - C++

Semantics of the compound assignment operators is different in C and C++:

C99 standard, 6.5.16, part 3:

> An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

In C++ 5.17.1:

> The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue with the type and value of the left operand after the assignment has taken place.

EDIT : The behavior of (i+=10)+=10 in C++ is undefined in C++98, but well defined in C++11. See this answer to the question by NPE for the relevant portions of the standards.

Solution 2 - C++

In addition to being invalid C code, the line

> (i+=10)+=10;

would result in undefined behaviour in both C and C++03 because it would modify i twice between sequence points.

As to why it's allowed to compile in C++:

> [C++N3242 5.17.1] The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

The same paragraph goes on to say that

> In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

This suggests that in C++11, the expression no longer has undefined behaviour.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSvetlin MladenovView Question on Stackoverflow
Solution 1 - C++Sergey KalinichenkoView Answer on Stackoverflow
Solution 2 - C++NPEView Answer on Stackoverflow