【问题标题】:Why is "++i++" invalid while (++i)++ is valid?为什么 "++i++" 无效,而 (++i)++ 有效?
【发布时间】:2020-03-09 11:29:30
【问题描述】:

让我们考虑以下代码:

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)。这是确切的渲染: 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 可以更清楚地看出问题出在前缀运算符上。

【问题讨论】:

  • 这最初是用 C 标记的,它肯定不是有效的 C。
  • 真的很抱歉!我认为 C 中的行为是相同的...

标签: c++ operators lvalue post-increment pre-increment


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    此声明

    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 是一个左值。 i++ 是一个右值(具体来说是右值)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-29
        • 2011-02-22
        • 2013-03-24
        • 1970-01-01
        • 2020-12-20
        • 2022-07-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多