【发布时间】:2014-07-21 05:16:27
【问题描述】:
我意识到仅仅询问未定义的行为会导致一些人投反对票,但我有一个问题比较 C99 与 2007 年 9 月(我唯一可以访问的,这对我很重要)和 2011 年的. 相关引用来自任一版本的 6.5 (2):
2007:“在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应只读先前值以确定要存储的值.(添加了突出显示)”
2011:“如果标量对象的副作用相对于同一标量对象的不同副作用或使用相同标量对象的值计算未排序,则行为未定义。(...)”
为了说明 2007 版本中的矛盾之处,举了一个例子:
i = ++i + 1;
由于 C 将赋值始终视为表达式(无赋值语句),因此该表达式在语义上由 2 个序列点描述。很明显,两个版本都声明上述内容会导致未定义的行为。
但是,鉴于 2007 版本中突出显示的句子,我的理解是,即使是以下表达式(再次位于两个序列点之间)也会导致未定义的行为:
++i; // or i++; or a = ++i;
,显然,“要存储的值”不仅是 read('stored' 有点模棱两可,但我自然会把它当作一次读取):它是读取的,递增的,然后存储回来。不过它是按顺序排列的,而且按照 2011 年的措辞来说非常好(可能应该如此)。
是否对措辞进行了调整以解决上述问题,以使意图与描述相匹配?
注意:我意识到这在一定程度上是基于意见的,但是 (1) 最好的情况是实际参与编写标准的人看到了这一点,并且 (2) 虽然我相信我的解释是合理的/"true",如果有人有力地反对它,这也很有用。
【问题讨论】:
-
如果能提供一些关于你在谈论什么章节/主题的线索。
-
我提到了准确的章节 - 6.5 (2)。
-
递增是“确定要存储的值”。
-
@RaymondChen:标准中没有定义“确定存储的值”(据我所知),整个问题是关于匹配意图和措辞。我显然同意它应该是合法的。
-
“确定存储的值”在英语中有其通常的含义:您可以加载该值,在计算中使用该值,然后存储计算结果。您不能加载该值并将其用于不相关的计算。用物理学术语来说,加载和存储必须是因果相关的。