Svetlin Mladenov
Svetlin Mladenov

Reputation: 4427

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

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?

Upvotes: 94

Views: 9063

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

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.

Upvotes: 136

NPE
NPE

Reputation: 500297

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.

Upvotes: 51

Related Questions