我有以下代码:
#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
为什么不同的行为?
das*_*ght 132
复合赋值运算符的语义在C和C++中是不同的:
C99标准,6.5.16,第3部分:
赋值运算符将值存储在左操作数指定的对象中.赋值表达式在赋值后具有左操作数的值,但不是左值.
在C++ 5.17.1中:
赋值运算符(=)和复合赋值运算符都是从右到左分组.所有都需要一个可修改的左值作为左操作数,并在赋值发生后返回左操作数的类型和值的左值.
编辑:(i+=10)+=10在C++ 98中,C++中的行为未定义,但在C++ 11中定义良好.请参阅NPE关于标准相关部分的问题的答案.
NPE*_*NPE 51
除了无效的C代码之外,该行
Run Code Online (Sandbox Code Playgroud)(i+=10)+=10;
会在C和C++ 03中导致未定义的行为,因为它会i在序列点之间修改两次.
至于为什么允许在C++中编译它:
[C++ N3242 5.17.1]赋值运算符(=)和复合赋值运算符从右到左分组.所有都需要一个可修改的左值作为左操作数,并返回一个左值操作数的左值.
同一段接着说
在所有情况下,分配的右侧和左侧的操作数的值计算后测序,并赋值表达式的值计算之前.
这表明在C++ 11中,表达式不再具有未定义的行为.