C 和 C + + 中 + = 的结果是什么?

我有以下密码:

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

如果我尝试使用 gcc 将它编译为 C 源代码,我会得到一个错误:

error: lvalue required as left operand of assignment

但是如果我使用 g + + 把它编译成 C + + 源代码,我就不会得到错误,而且当我运行可执行文件时:

i = 20

为什么不同的行为?

8601 次浏览

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.

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.