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

时间:2012-05-18 13:50:54

标签: 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

为什么不同的行为?

2 个答案:

答案 0 :(得分:132)

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

C99标准,6.5.16,第3部分:

  

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

在C ++ 5.17.1中:

  

赋值运算符(=)和复合赋值运算符从右到左分组。所有都需要修改   左值作为左操作数,并在赋值发生后返回左值操作数的类型和值的左值。

编辑: C ++中(i+=10)+=10的行为在C ++ 98中未定义,但在C ++ 11中定义良好。有关标准的相关部分,请this answer查看问题的NPE

答案 1 :(得分:51)

除了无效的C代码外,该行

(i+=10)+=10;

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

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

  

[C ++ N3242 5.17.1]赋值运算符(=)和复合赋值运算符从右到左分组。都需要一个   可修改左值作为左操作数并返回左值操作数的左值。

同一段继续说

  

在所有情况下,分配都在值之后排序   计算右和左操作数,并在赋值表达式的值计算之前。

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