[英]Why is “++i++” invalid while (++i)++ is valid?
Let's consider the following code:让我们考虑以下代码:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
It compiles with the following with an error:它编译时出现以下错误:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
This sounds fair to me.这对我来说听起来很公平。 Postfix increment has higher priority than prefix increment, so the code is parsed as
int b = ++(i++);
后缀自增优先级高于前缀自增,因此代码解析为
int b = ++(i++);
and i
is an rvalue. i
是一个右值。 Hence the error.因此错误。
Let's now consider this variant with parenthesis to override default priorities:现在让我们考虑这个带括号的变体来覆盖默认优先级:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
This code compiles and returns 3. On its own, this sounds fair to me but it seems in contradiction with the first code.此代码编译并返回 3。就其本身而言,这对我来说听起来很公平,但它似乎与第一个代码相矛盾。
The question: why (++i)
is an lvalue
when i
is not?问题:为什么
(++i)
是lvalue
,而i
不是?
Thanks!谢谢!
UPDATE: the error message shown above was from gcc (x86-64 9.2).更新:上面显示的错误消息来自 gcc (x86-64 9.2)。 Here is the exact rendering: error with gcc
这是确切的渲染: gcc 的错误
Clang x86-64 9.0.0 has a quite different message: error with clang Clang x86-64 9.0.0 有一条完全不同的消息: clang 出错
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
With GCC, you get the impression that the problem is with the postfix operator and you can then wander why ++i
is OK while i
is not, hence my question.使用 GCC,您会得到这样的印象,即问题出在后缀运算符上,然后您可以徘徊为什么
++i
可以而i
不行,因此我的问题。 With Clang it is clearer that the problem is with the prefix operator.使用 Clang 可以更清楚地看出问题出在前缀运算符上。
i
and ++i
are both lvalues, but i++
is an rvalue. i
和++i
都是左值,但i++
是右值。
++(i++)
cannot be valid, as the prefix ++
is being applied to i++
, which is an rvalue. ++(i++)
无效,因为前缀++
被应用于i++
,这是一个右值。 But (++i)++
is fine because ++i
is an lvalue.但是
(++i)++
很好,因为++i
是一个左值。
Note that in C, the situation is different;注意在C中情况不同;
i++
and ++i
are both rvalues. i++
和++i
都是右值。 (This is an example of why people should stop assuming that C and C++ have the same rules. People insert these assumptions into their questions, which must then be refuted.) (这是为什么人们应该停止假设 C 和 C++ 具有相同规则的示例。人们将这些假设插入到他们的问题中,然后必须予以反驳。)
This declaration本声明
int b = ++i++;
is equivalent to相当于
int b = ++( i++ );
The postfix increment operator returns the value of the operand before increment.后缀自增运算符返回自增前操作数的值。
From the C++ 17 Standard (8.2.6 Increment and decrement)来自 C++ 17 标准(8.2.6 递增和递减)
1 The value of a postfix ++ expression is the value of its operand... The result is a prvalue .
1 后缀 ++ 表达式的值是其操作数的值...结果是 prvalue 。
While the unary increment operator returns lvalue after its increment.而一元自增运算符在自增后返回左值。 So this declaration
所以这个声明
int b = (++i)++;
is valid.已验证。 You could for example write
你可以例如写
int b = (++++++++i)++;
From the C++ 17 Standard (8.3.2 Increment and decrement)来自 C++ 17 标准(8.3.2 递增和递减)
1 The operand of prefix ++ is modified by adding 1. The operand shall be a modifiable lvalue.
1 前缀 ++ 的操作数通过加 1 进行修改。操作数应为可修改的左值。 The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a completely-defined object type.
操作数的类型应为除 cv bool 以外的算术类型,或指向完全定义的 object 类型的指针。 The result is the updated operand;
结果是更新的操作数; it is an lvalue , and it is a bit-field if the operand is a bit-field....
它是一个左值,如果操作数是一个位域,它就是一个位域....
Pay attention that in C the both operators return a value instead of lvalue.请注意,在 C 中,两个运算符都返回一个值而不是左值。 So in C this declaration
所以在 C 这个声明
int b = (++i)++;
is invalid.是无效的。
so the code is parsed as int b = ++(i++);
所以代码被解析为 int b = ++(i++); and i is an rvalue.
i 是一个右值。
No. i
is not an rvalue.不,
i
不是右值。 i
is an lvalue. i
是一个左值。 i++
is an rvalue (prvalue to be specific). i++
是一个右值(具体来说是右值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.