为什么 C99 中的这个语句在 C11 中发生了变化?

7 c object c99 language-lawyer c11

C99标准:

在上一个和下一个序列点之间,一个对象的存储值最多应通过表达式的评估修改一次

C11标准:

如果一个标量对象的副作用相对于同一个标量对象的另一个副作用是无序的,则行为是未定义的。

那么 C99 标准的这个定义是否不完整,因此它在 C11 中进行了更新,因为它只包含术语object而不包含术语scalar object

Lun*_*din 6

这是因为 C11 试图涵盖多线程/并行执行。“抽象机器”中程序执行的基本规则在C99和C11之间添加了这段繁琐的文字(C11 5.1.2.3/3):

Sequenced before 是由单个线程执行的评估之间的不对称、可传递、成对关系,这会导致这些评估之间存在偏序。给定任意两个评估 A 和 B,如果 A 在 B 之前被排序,那么 A 的执行应该在 B 的执行之前。(相反,如果 A 在 B 之前被排序,那么 B 在 A 之后被排序。)如果 A 没有被排序在 B 之前或之后,则 A 和 B 是未排序的。当 A 在 B 之前或之后排序时,评估 A 和 B 是不确定的排序,但未指定哪个。 13) 在表达式 A 和 B 的评估之间存在序列点意味着每个值计算和与 A 相关的副作用在与 B 相关的每个值计算和副作用之前排序。

因此,您引用的部分 (C99 6.5/2) 进行了相应的更改,以适应抽象机中程序执行的定义,据说现在也涵盖了并行执行。不幸的是 - 由于 C99 文本更具可读性。从技术上讲,如果不考虑并行执行,则根本没有任何变化。C99 中关于序列点的规则仍然适用,只是措辞不同。此更改还意味着将 C11 与具有类似规则的 C++11 同步。