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

时间:2019-11-13 15:59:45

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

让我们考虑以下代码:

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)不是lvalue时,i<source>:3:13: error: expression is not assignable int b = ++i++; ^ ~~~

谢谢!

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

Clang x86-64 9.0.0具有完全不同的消息: error with clang

++i

使用GCC,您会发现问题出在postfix运算符上,然后您就可以绕开为什么i可以而SELECT * FROM `wp_postmeta` WHERE `meta_key` = '_stock_status' 不好的原因,因此是我的问题。使用Clang可以清楚地知道问题出在前缀运算符上。

3 个答案:

答案 0 :(得分:23)

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

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

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

答案 1 :(得分: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)++;

无效。

答案 2 :(得分:3)

  

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

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