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

为什么不同的行为?

Svetlin Mladenov asked 2019-08-10T12:54:01Z
2个解决方案
132 votes

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

C99标准,6.5.16,第3部分:

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

在C ++ 5.17.1中:

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

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

dasblinkenlight answered 2019-08-10T12:54:50Z
51 votes

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

(i+=10)+=10;

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

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

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

同一段接着说

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

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

NPE answered 2019-08-10T12:56:06Z
translate from https://stackoverflow.com:/questions/10653903/whats-the-result-of-in-c-and-c