导致错误的后缀和前缀增量

Postfix and prefix increment that causes an error

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

#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 值,我不在乎为什么 ++i 被认为是左值,但 i++ 不是。

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

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

上述规则的原因是 post-increment 需要 return 应用增量之前的对象值。顺便说一句,这就是为什么在一般情况下 post-incrememts 在用于非内置对象时被认为比预增量更昂贵。

简而言之,不同之处在于,在 C++ 中,您可以像这样对前缀增量运算符使用任意偶数个加号(仅受编译器限制)

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

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

i++;

post固定增量运算符returns一个值(C++标准,5.2.6增量和减量)

1 The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value —end note ]

而前缀自增运算符returns其操作数自增后(C++标准,5.3.2自增自减)

1 ...The result is the updated operand; it is an lvalue...

与 C++ 中的 C++ 相反,您也可以使用前缀递增运算符仅将两个加号应用于对象。:) 因此,C 编译器将针对这样的表达式发出错误

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

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

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

也许从 ++ 运算符开始比较好。事实上它是 shorthand for i = i + 1。现在,如果我们查看后缀版本 i++,它在标准中表示它 returns 原始值的副本,并且作为 side efect 它会增加原始值。 所以从 (i++) 你得到右值并试图分配给它,正如我们所知你不能分配给右值。