在C ++中,

i = ++++j;


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

i = j++++;


我收到以下错误:

Operand for operator "++" must be an lvalue.


为什么会出现此错误?

最佳答案

后递增要求操作数应为可修改的左值,但后递增的结果为不可修改的prvalue(“纯”右值),此图显示了发生了什么:

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


如果需要了解左值和右值之间的区别,Understanding lvalues and rvalues in C and C++是一个不错的起点。
draft C++ standard部分5.2.6递增和递减[expr.post.incr]第1段说(这里重点是我的后引号):


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


更新资料

由于在C ++ 03和C ++ 11之间存在差异,因此我对未定义行为进行了重新设计。

尽管显示了第一个表达式:

i = ++++j ;


不会产生错误,但是如果它是C ++ 03并且j是基本类型,则它是undefined behavior,因为未定义在sequence point中多次修改其值的情况。 older draft standard中的相关部分将是5表达式第4段,其中指出:


  在上一个序列点和下一个序列点之间,标量对象应通过表达式的计算最多对其存储值进行一次修改。此外,应仅访问先验值以确定要存储的值。对于完整表达式的子表达式的每个允许的排序,都应满足本段的要求;否则,行为是不确定的。


并给出了一些示例,其中一个如下:

i = ++i + 1; // the behavior is undefined


在C ++ 11中,相对于相同对象上的另一个副作用,未对相同标量对象上的副作用进行语言更改,因此未定义行为。因此,这实际上在C ++ 11中得到了很好的定义,在1.9程序执行第15段中说:


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


以这种方式使用后增量和前增量在两种情况下都不会导致使用j +=2的可读(可维护)代码,无论是在赋值语句之前还是之后

关于c++ - 错误:运算符“++”的操作数必须为左值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18819570/

10-11 23:07