我已经阅读了有关评估顺序的内容,并且我理解了评估顺序导致的一些错误。
我的基本规则来自文字和示例:
- 操作数评估的顺序与优先级和关联性无关。
- 在大多数情况下,订单很大程度上没有说明。
所以表达式如下:int i = f1() * f2();
必须在乘法完成之前调用f1和f2。毕竟,他们的结果是成倍增加的。但是,我们无法知道在f2之前是否会调用f1,反之亦然。
未定义的行为示例:
int i = 0;
cout << i << " " << ++i << endl;
我的理解:我将i
和++i
视为一种功能。我不知道首先评估哪个,因此第一个i
可能是0
或1
而且(规则)是有道理的。
while(beg != s.end())
*beg = toupper(*beg++); //Just another example.
我认为理解这一点的关键是将每个操作数视为&#34;评估单位&#34;,并且一个人不知道这些单位内的评估顺序,但可以知道每个单个单位。
但对于i = ++i + 2
reference here,为什么会出错?我无法用自己的结论来解释。
左i
用作左值,不是指针。 ++i
只是重写原始值并且不会更改存储地址。如果它评估第一个或后一个可能有什么问题?我的规则失败了。
很长但是尽量提供足够的背景信息,感谢您的耐心等待。
我不知道答案中经常提到的序列点。所以我想我需要先阅读一些有关它的内容。顺便说一句,争论不是很有帮助,因为新手只是想知道为什么它被认为是错误的,就像在C ++ 11之前一样?
我发现这个答案Undefined behavior and sequence points解释了为什么i = ++i + 2
在C ++ 11之前是未定义的行为
答案 0 :(得分:4)
C ++ 11有新的排序规则。特别地,对于预增量(++i
),在进一步使用新的递增值之前,对副作用(写入新值)进行排序。由于赋值i=
在对其右侧进行评估之后进行了排序,这意味着在写++i
i=(++i + 2)
是传递顺序的。
i=(i++ + 2)
将是另一回事。对于后增量,副作用是后续的,这意味着两个分配不再相对于彼此排序。这是未定义的行为。
答案 1 :(得分:-3)
你的两个&#34;子功能&#34; i = ++i + 2
中的=
运算符明确赋值,++
运算符执行隐式赋值。
preincrement运算符被定义为返回变量的递增值,这肯定应该用于加法(由+
运算符执行)。但是,它没有定义,当时,递增的值应该存储回i
。
因此,未确定i
的最终值是old_i incremented plus 2
还是old_i incremented
。