C99 §6.5表达式
(1) 表达式是一系列运算符和操作数,用于指定值的计算,或指定对象或函数,或产生副作用,或执行它们的组合。
(2) 在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。72)此外,应仅读取先验值以确定要存储的值。73)
带脚注
72) 浮点状态标志不是对象,可以在表达式中多次设置。
73) 本段呈现未定义的语句表达式,例如
i = ++i + 1; a[i++] = i;
同时允许
i = i + 1; a[i] = i;
其中 C11 §6.5 更改为((1) 的文本有一个附录):
(1) […] 运算符的操作数的值计算在运算符结果的值计算之前排序。
(2) 如果标量对象的副作用相对于同一标量对象的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义。如果一个表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为是未定义的。84)
其中 C11 中的脚注 84 与 C99 中的脚注 73 相同。
我有点困惑...我将 C11 (2) 读为“[...] (对同一标量对象的不同副作用)或(使用同一标量对象的值的值计算)[...]”,这似乎甚至不允许foo = ++i
(有一个副作用,我们根据更改的对象使用一个值)。不过,我不是母语人士,所以如果有人能告诉我应该如何“解析”这句话,那就太好了。我了解C99,但我不太了解C11的措辞。
无论如何,实际的问题是:这是从 C99 到 C11 的变化,还是这些措辞是等价的?如果是这样,为什么它被改变了?如果没有,有人可以举一个表达式的例子,它在 C99 中是 UB,但在 C11 中不是,反之亦然?