导致错误的后缀和前缀增量
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++) 你得到右值并试图分配给它,正如我们所知你不能分配给右值。
为什么该代码由于错误而无法编译:
#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++) 你得到右值并试图分配给它,正如我们所知你不能分配给右值。