在C ++中,
i = ++++j;
在代码中工作正常,但是当我使用时,
i = j++++;
我收到以下错误:
Operand for operator "++" must be an lvalue.
为什么我收到此错误?
答案 0 :(得分:7)
后增量要求操作数应该是可修改的左值,但后增量的结果是prvalue(“纯”右值)不可修改,此图表显示了正在发生的事情:
i = (j++)++ ;
^ ^
| |
| Result is a prvalue, not a valid operand for subsequent post-increment
Modifiable lvalue
如果您需要了解 lvalues 和 rvalues 之间的区别, Understanding lvalues and rvalues in C and C++是一个很好的起点。
从draft C++ standard部分5.2.6
增量和减量[expr.post.incr] 段 1 说(重点是我的后续报价):
后缀++表达式的值是其操作数的值。 [注意:获得的值是原始值的副本-end note] 操作数应是可修改的左值。 [..] 结果是prvalue。
更新
我在未定义的行为上重写了我的语言,因为这里有关于 C ++ 03 和 C ++ 11 的区别。
虽然显示了第一个表达式:
i = ++++j ;
不会生成错误,但如果这是 C ++ 03 且j
是基本类型,那么这是undefined behavior,因为在sequence point内修改它的值不止一次{3}}未定义。 older draft standard中的相关部分为5
表达式段 4 ,其中包含:
[...] 在上一个和下一个序列点之间,标量对象的表达式评估最多只能修改一次的存储值。此外,只能访问先前值以确定要存储的值。对于完整表达式的子表达式的每个允许排序,应满足本段的要求; 否则行为未定义。
并给出了一些例子,其中一个如下:
i = ++i + 1; // the behavior is undefined
在 C ++ 11 中,对于相同标量对象的副作用的语言更改相对于对同一对象的另一个副作用是未排序的,则行为未定义。所以这实际上已在 C ++ 11 中明确定义,在1.9
部分段落 15 中说:
除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不确定的。 [...] 如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义。
以这种方式使用后增量和预增量不会导致在赋值语句足够之前或之后使用j +=2
的两种情况下的可读(可维护)代码
答案 1 :(得分:1)
您收到此错误,因为后缀运算符返回值而不是引用。但为了清楚起见,您可能不应该i=j++++;
更明确地说i = j += 2;
或将这些行分为i = j+2; j+=2;
或j+=2; i = j;
。