Postfix和前缀增量导致错误

时间:2017-07-07 18:18:02

标签: c++ increment postfix-notation prefix-notation

为什么该代码由于错误而无法编译:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << ++(i++) << " " << i << endl;
    return 0;
}

虽然该代码确实编译:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << (++i)++ << " " << i << endl;
    return 0;
}

我不明白。从我的角度来看,编译第一个块是非常合理的。表达式++(i ++)只是意味着取i,递增和输出,然后再增加它。

我不是在询问int溢出中的未定义行为。在撰写问题时我根本不知道r和l值,我不在乎为什么++我被认为是l值,但i ++不是。

3 个答案:

答案 0 :(得分:6)

这是因为post增量和pre增量运算符返回不同类型的值。后增量的结果是所谓的'rvalue',意味着它不能被修改。但预增量需要一个可修改的值来增加它!

另一方面,预增量的结果是左值,这意味着它可以通过后增量安全地修改。

以上规则的原因是后增量需要返回对象的值,就像应用增量之前一样。顺便说一下,这就是为什么一般情况下,在非内置对象上使用后增量被认为比预增量更昂贵。

答案 1 :(得分:2)

简而言之,不同之处在于,在C ++中,您可以使用任何偶数个加号(仅限于编译器限制)作为前缀增量运算符,如下所示

++++++++++++++++i;

并且后增量运算符只有两个加号

i++;

后缀增量运算符返回一个值(C ++标准,5.2.6增量和减量)

  

1后缀++表达式的值是其值   操作数即可。 [注意:获得的值是原始值的副本    - 后注]

前缀增量运算符在递增后返回其操作数(C ++标准,5.3.2增量和减量)

  

1 ... 结果是更新的操作数;这是一个左值 ......

在C语言中与C ++相反,你也可以使用前缀增量运算符仅对对象应用两个加号。:)因此,C编译器会为这样的表达式发出错误

++++++++++++++++i;

答案 2 :(得分:1)

当您使用clang编译它时,您会收到错误消息,说明这一切。

<source>:8:13: error: expression is not assignable
cout << ++(i++) << " " << i << endl;

从++运算符开始也许是件好事。实际上它是i = i + 1的简写。现在,如果我们看一下postfix版本i ++,它会在标准中说它返回原始值的副本,并且side efect它会增加原始值。 所以从(i ++)你得到rvalue并试图分配它,因为我们知道你不能分配到rvalue。