澄清c。/改变C99标准的措辞

时间:2014-05-31 15:20:22

标签: c c99

我意识到仅仅询问未定义的行为导致一些人的支持,但我有一个问题,比较C99诉2007年9月(我唯一可以访问的,对我来说很重要)和2011年的问题。相关报价均为6.5(2)版本:

  

2007:“在上一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该是只读的,以确定要存储的值。(突出显示已添加)“

     

2011:“如果相对于相同标量对象的不同副作用或使用相同标量对象的值计算,标量对象的副作用未被排序,则行为未定义。(...)”< / p>

用于说明2007版本中与此相矛盾的一个例子是:

i = ++i + 1;    

由于C认为赋值总是一个表达式(没有赋值语句),因此该表达式在语义上由2个序列点描述。很明显,两个版本声明上述内容都会导致未定义的行为。

然而,鉴于2007版本的突出显示的句子,我的理解是即使下面的表达式(在两个序列点之间再次存在)也会导致未定义的行为:

  ++i; // or i++;  or a = ++i;   

,显然,“要存储的值”不仅仅是('存储'有点含糊不清,但我自然会把它读成一个读取):它被读取,递增,然后存储回来。它按顺序进行排序,并且2011年的措辞非常好(可能应该如此)。

是否对上述措辞进行了调整,以便将意图与描述相匹配?

注意:我意识到这在某种程度上是基于意见的,但(1)最好的情况是,实际参与编写标准的人会看到这一点,(2)虽然我认为我的解释是合理的/“真实”,如果有人以令人信服的方式反对它,这也是有用的。

1 个答案:

答案 0 :(得分:4)

  

然而,鉴于2007版本的突出显示的句子,我的理解是即使下面的表达式(在两个序列点之间再次存在)也会导致未定义的行为:

 ++i; // or i++;  or a = ++i;  
你理解错了。最好在c-faq question-3.8中解释:

  

....这就是第二句话所说的:如果一个对象被写入一个完整的表达式,那么在同一个表达式中对它的任何和所有访问都必须直接参与计算值写的。此规则有效地将法律表达式约束为在修改之前明显存在访问的表达式。例如,允许使用旧备用i = i + 1,因为i的访问权限用于确定i的最终值。例子

  a[i] = i++  
     

禁止,因为ia[i]中的一个)的访问与最终存储在i (在i++中发生),因此没有好的方法来定义 - 无论是我们的理解还是编译器 - 是否应该在存储增量值之前或之后进行访问。

如果i++;++i; i的访问权限及其增量与最终存储在i中的值有关。