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

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

本文关键字:结果 结果是 是什么 C++      更新时间:2023-10-16

我有以下代码:

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

如果我尝试使用 gcc 将其编译为 C 源,则会出现错误:

error: lvalue required as left operand of assignment

但是,如果我使用 g++ 将其编译为C++源,则不会出错,并且当我运行可执行文件时:

i = 20

为什么会有不同的行为?

复合

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

C99 标准,6.5.16,第 3 部分:

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

在 5.17.1 C++:

赋值运算符 (=( 和复合赋值运算符都从右到左分组。都需要可修改的 lvalue 作为其左操作数,并在赋值发生后返回一个包含左操作数类型和值的 lvalue。

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

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

(i+=10)+=10;

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

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

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

同一段接着说,

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

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

相关文章: