为什么 i = ++i + 2 是未定义的行为?
why i = ++i + 2 is undefined behavior?
我读过一些关于评估顺序的东西,我理解由评估顺序引起的一些错误。
我的基本规则来自文本和示例:
- 操作数计算的顺序与优先级和关联性无关。
- 在大多数情况下,顺序在很大程度上是未指定的。
所以对于这样的表达:int i = f1() * f2();
必须先调用 f1 和 f2,然后才能完成乘法。毕竟,是他们的结果成倍增加。但是,我们无法知道 f1 是否会在 f2 之前调用,反之亦然。
未定义的行为示例:
int i = 0;
cout << i << " " << ++i << endl;
我如何理解:我将i
和++i
视为一种功能。我不知道哪个先评估,所以第一个i
可能是0
或1
,(规则(是有意义的。
while(beg != s.end())
*beg = toupper(*beg++); //Just another example.
我认为理解这一点的关键是将每个操作数视为一个"评估单元",人们不知道这些单元内的评估顺序,但可以知道每个单元中的顺序。
但在这里供i = ++i + 2
参考,为什么是错的? 我无法用我自己的结论来解释。
左i
用作左值而不是指针。++i
只是重写原始值,不会更改存储地址。如果它先评估还是后评估,可能会出错?我的规则在这里失败了。
很长,但尽量提供足够的背景信息,感谢您的耐心等待。
我不知道答案中经常提到的序列点。所以我想我需要先阅读一些关于它的东西。顺便说一句,辩论不是很有帮助,因为新手只是想知道为什么它被认为是错误的,就像 C++11 之前一样?
我发现这个答案 未定义的行为和序列点很好地解释了为什么i = ++i + 2
C++11 之前是未定义的行为
C++11 有了新的排序规则。特别是,对于预递增(++i
(,副作用(写入新值(在进一步使用新的递增值之前被排序。由于赋值i=
是在评估其右侧之后排序的,这意味着写++i
在写i=(++i + 2)
之前传递排序
这对i=(i++ + 2)
来说将是另一回事.对于后递增,副作用是后排序的,这意味着两个赋值不再相对地排序。这是未定义的行为。
i = ++i + 2
中的两个"子函数"是由=
运算符进行的显式赋值和由++
运算符完成的隐式赋值。
preincrement 运算符被定义为返回变量的增量值,这绝对应该用于加法(由+
运算符执行(。但是,它没有定义,何时应将递增的值存储回i
。
因此,无法确定i
的最终值是old_i incremented plus 2
还是只是old_i incremented
。
- 编译C++时未定义的引用
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- c++11评估顺序(未定义的行为)
- 使用mysql c++连接器的未定义引用
- 从python调用openMP共享库时,未定义opnMP函数
- 在 Mac 上使用 CMAKE 将 FFTW 和 FFTWPP 链接到项目中时未定义的符号
- Cmake 链接问题:未定义对 Button::mousePressEvent(QGraphicsSceneMouseE
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 具有外部"c"和程序集的未定义函数
- 此增量后语句是否会导致未定义的行为?
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在C++中使用内联方法时出现未定义的符号错误
- 对 Scalar ::Scalar() 的未定义引用