简体   繁体   English

为什么“++i++”无效而(++i)++有效?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM