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

Error : Operand for operator "++" must be an lvalue

本文关键字:运算符 错误 操作数      更新时间:2023-10-16

In 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

如果您需要了解值和右值之间的区别,了解 C 和 C++ 中的左值和右值是一个很好的起点。从草案C++标准部分5.2.6增和递减[expr.post.incr]1段说(在后面的引文中强调):

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

更新

我重新设计了关于未定义行为的语言,因为这里与 C++03C++11 有所不同。

虽然第一个表达式显示:

i = ++++j ;

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

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

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

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

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

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

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

您收到此错误是因为后缀运算符返回值而不是引用。但为了清楚起见,您可能不应该这样做i=j++++;i = j += 2;或将行分成 i = j+2; j+=2;j+=2; i = j; 可能更清楚。