为什么i = ++ i + 2是未定义的行为?

时间:2018-06-19 09:05:50

标签: c++ operator-precedence

我已经阅读了有关评估顺序的内容,并且我理解了评估顺序导致的一些错误。

我的基本规则来自文字和示例:

  
      
  • 操作数评估的顺序与优先级和关联性无关。
  •   
  • 在大多数情况下,订单很大程度上没有说明。
  •   

所以表达式如下:int i = f1() * f2();

  必须在乘法完成之前调用

f1和f2。毕竟,他们的结果是成倍增加的。但是,我们无法知道在f2之前是否会调用f1,反之亦然。

未定义的行为示例:

int i = 0;
cout << i << " " << ++i << endl; 

我的理解:我将i++i视为一种功能。我不知道首先评估哪个,因此第一个i可能是01而且(规则)是有道理的。

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之前是未定义的行为

2 个答案:

答案 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