在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 

为什么不同的行为?

C和C ++中复合赋值运算符的语义不同:

C99标准,6.5.16,第3部分:

赋值运算符将值存储在由左操作数指定的对象中。 赋值expression式在赋值后具有左操作数的值,但不是左值。

在C ++ 5.17.1中:

赋值运算符(=)和复合赋值运算符全部从右到左。 所有这些操作都需要一个可修改的左值作为它们的左操作数,并在赋值发生后返回左操作数的types和值的左值。

编辑: C (i+=10)+=10(i+=10)+=10的行为在C ++ 98中是未定义的,但是在C ++ 11中定义良好。 请参阅NPE关于标准相关部分的问题的答案 。

除了无效的C代码之外

 (i+=10)+=10; 

会在C和C ++ 03中导致未定义的行为,因为它会在序列点之间修改两次。

至于为什么允许用C ++编译:

[C ++ N3242 5.17.1]赋值运算符(=)和复合赋值运算符全部从右到左。 所有需要一个可修改的左值作为它们的左操作数, 并返回一个指向左操作数的左值。

同一段落继续说

在任何情况下,赋值都是在左右操作数的值计算之后,赋值expression式的值计算之前进行sorting的。

这表明在C ++ 11中,expression式不再具有未定义的行为。