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


14

让我们考虑以下代码:

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;
}

该代码将编译并返回3。对我来说,这听起来很公平,但似乎与第一个代码矛盾。

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

谢谢!

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

Clang x86-64 9.0.0有一个完全不同的消息: clang错误

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

    int b = ++i++;

            ^ ~~~

使用GCC,您会感觉到问题出在postfix运算符上,然后您可以在为什么可以确定的++i同时i又可以在为什么不可以的情况中徘徊,因此是我的问题。使用Clang可以清楚地知道问题出在前缀运算符上。


这原本是标有C,它肯定是无效C.
安蒂·哈帕拉

的确对不起!我假设的行为是在C一样的...
Bktero

Answers:


23

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

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

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


4

这个宣言

int b = ++i++;

相当于

int b = ++( i++ );

后缀增量运算符返回增量之前的操作数的值。

从C ++ 17标准起(8.2.6递增和递减)

1后缀++表达式的值是其操作数的值... 结果是prvalue

一元增量运算符在其增量后返回左值。所以这个宣言

int b = (++i)++;

已验证。你可以例如写

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

根据C ++ 17标准(8.3.2递增和递减)

1前缀++的操作数通过加1进行修改。操作数应为可修改的左值。操作数的类型应为cv bool以外的算术类型,或为完全定义的对象类型的指针。结果是更新的操作数;它是一个左值,如果操作数是一个位域,它是一个位域。

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

int b = (++i)++;

是无效的。


3

因此代码被解析为int b = ++(i ++); 我是一个右价值。

i不是右值。i是左值。i++是右值(具体来说是右值)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.