C++0x learning: Sequencing rules of assignment.
众所周知,在C++2003中,表达式的求值顺序,以及其中的副作用(side effects)发生的顺序都是不确定的。
所以对于表达式i = ++i + 1; 其i的值是undefined. [ref1][ref2]
到了C++0x(draft-N3242[ref3]),表达式的求值顺序依然是不确定的,但是对于赋值操作符(assignment),C++0x增加一个新的规定,这导致i = ++i + 1不再是undefined得了.
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
在这里[Ref4]阐述了为什么 i = ++i + 1; 不再为undefined,大意如下
1. 复制操作的副作用要等到左右操作数的值都计算晚了。
2. 对于左边的 i, 需要计算lvalue, 这个值不论何时计算都是不变的。
3. 对于右边,如果要计算表达是 ( ++i + 1)的值。首先要计算++i的左值,然后做 lvalue-to-rvalue conversion得到右值。这保证了自增的side effect会在其他操作数的求值之前发生。也就是说会在赋值语句的side effect之前发生。
并且也解释了对于i = i++ +1; 因为i++的值就是i的值,其自增的side effect执行点依然是不确定的,所以其值依然是不确定的。
那么i += ++i如何呢? 这是undefined的. 因为 i += ++i 等于 i = i + ++i. 对于=左边的i, 不仅要求左值,还要求右值,右值会被++i的求值顺序所影响. [ref5]
[ref2]Why is `i = ++i + 1` unspecified behavior?(http://stackoverflow.com/questions/1860461/why-is-i-i-1-unspecified-behavior/1860704#1860704)
[ref4] Sequencing rules and example disagree(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637)
[ref5] Is i += ++i undefined behavior in C++0x?(http://stackoverflow.com/questions/3932287/is-i-i-undefined-behavior-in-c0x/3933894#3933894)
欢迎讨论,但是请勿发表"研究这些细节无用“的言论。对于C++的偏执狂来说,研究标准的这些细枝末节是很有趣的事情。