错误:操作符"++"的操作数必须是左值

use*_*405 0 c++

在C++中,

i = ++++j;
Run Code Online (Sandbox Code Playgroud)

在代码中工作正常,但是当我使用时,

i = j++++;
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Operand for operator "++" must be an lvalue.
Run Code Online (Sandbox Code Playgroud)

为什么我收到此错误?

Sha*_*our 7

后增量要求操作数应该是一个可修改的左值,但后增量的结果是一个不可修改的prvalue("纯"rvalue),此图显示了正在发生的事情:

i = (j++)++ ;
     ^  ^
     |  |
     |  Result is a prvalue, not a valid operand for subsequent post-increment
     Modifiable lvalue
Run Code Online (Sandbox Code Playgroud)

了解C和C++左值和右值是,如果你需要明白之间的差别,以一个良好的开端左值右值.从草案C++标准部分5.2.6 增加和减少[expr.post.incr]1段说(重点是我的后续引用):

后缀++表达式的值是其操作数的值.[注意:获得的值是原始值的副本-end note] 操作数应该是可修改的左值.[..] 结果是一个prvalue.

更新

我在未定义的行为上重写了我的语言,因为这里与C++ 03C++ 11有所不同.

虽然第一个表达式显示:

i = ++++j ;
Run Code Online (Sandbox Code Playgroud)

不产生错误,但如果这是C++ 03并且j是基本类型,则这是未定义的行为,因为在序列点内多次修改它的值是未定义的.较旧的标准草案中的相关部分将是5 表达4段的部分,其中说:

[...] 在前一个和下一个序列点之间,标量对象的表达式评估最多只能修改一次存储值.此外,只能访问先前值以确定要存储的值.对于完整表达式的子表达式的每个允许排序,应满足本段的要求; 否则行为未定义.

它给出了一些例子,其中一个例子如下:

i = ++i + 1; // the behavior is undefined
Run Code Online (Sandbox Code Playgroud)

C++ 11中,相对于同一个对象的另一个副作用,相同标量对象的副作用的语言更改是未排序的,然后行为未定义.所以这在C++ 11中实际定义得很好,在1.9 程序执行15段中说:

除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不确定的.[...] 如果标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值的计算值未被排序,则行为未定义.

以这种方式使用后增量和预增量在两种情况下都不会导致可读(可维护)代码,使用j +=2赋值语句之前或之后就足够了