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

Why is "++i++" invalid while (++i)++ is valid?

让我们考虑以下代码:

int main() {
    int i = 2;
    int b = ++i++;
    return 3;
}

编译时出现以下错误:

<source>: In function 'int main()':

<source>:3:16: error: lvalue required as increment operand

    3 |     int b = ++i++;

      |                ^~

这听起来很公平。后缀自增优先级高于前缀自增,所以代码被解析为int b = ++(i++);i是一个右值。因此错误。

现在让我们考虑使用括号覆盖默认优先级的变体:

int main() {
    int i = 2;
    int b = (++i)++;
    return 3;
}

此代码编译 returns 3. 就其本身而言,这对我来说听起来很公平,但似乎与第一个代码矛盾。

问题:为什么 (++i)lvaluei 不是?

谢谢!

更新: 上面显示的错误消息来自 gcc (x86-64 9.2)。这是确切的渲染: error with gcc

Clang x86-64 9.0.0 有一个完全不同的信息: error with clang

<source>:3:13: error: expression is not assignable

    int b = ++i++;

            ^ ~~~

使用 GCC,您会觉得问题出在后缀运算符上,然后您可能会想为什么 ++i 可以,而 i 不行,因此我的问题。使用 Clang 更清楚问题出在前缀运算符上。

i++i 都是左值,但 i++ 是右值。

++(i++) 无效,因为前缀 ++ 被应用于 i++,这是一个右值。但是 (++i)++ 很好,因为 ++i 是一个左值。

请注意,在C 中,情况有所不同; i++++i 都是右值。 (这是一个例子,说明为什么人们应该停止假设 C 和 C++ 具有相同的规则。人们将这些假设插入到他们的问题中,然后必须反驳这些假设。)

so the code is parsed as int b = ++(i++); and i is an rvalue.

没有。 i 不是右值。 i 是一个左值。 i++ 是一个右值(具体来说是右值)。

这个声明

int b = ++i++;

相当于

int b = ++( i++ );

后缀递增运算符return是递增前操作数的值。

来自 C++ 17 标准(8.2.6 递增和递减)

1 The value of a postfix ++ expression is the value of its operand...The result is a prvalue.

而一元递增运算符 return 是递增后的左值。所以这个声明

int b = (++i)++;

有效。例如,您可以写

int b = (++++++++i)++;

来自 C++ 17 标准(8.3.2 递增和递减)

1 The operand of prefix ++ is modified by adding 1. The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type other than cv bool, or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field....

注意在 C 中,两个运算符 return 都是一个值而不是左值。所以在 C 中这个声明

int b = (++i)++;

无效。