我看不懂C99中的一些句子

Posted

技术标签:

【中文标题】我看不懂C99中的一些句子【英文标题】:I can not understand some sentences in C99 【发布时间】:2013-10-02 17:21:53 【问题描述】:

在 C99 6.5 中说:

在前一个序列点和下一个序列点之间,一个对象应该有它的 表达式的评估最多修改一次存储的值。 此外,应仅读取先验值以确定该值 储存起来

“此外,应仅读取先验值以确定要存储的值”是什么意思?在 C99 中,为什么 a[i++] = 1 是未定义的行为?

【问题讨论】:

见this、this和this,甚至可能是this。 @PascalCuoq,你可以把它变成一个答案。这可能是解释序列点的一个很好的例子。 @s.bandara 各种linked问题已经很详细地解释了。 语言规范是编程语言的法律术语,它们也很有趣。也就是说,不是很多。 OP还特别询问,“此外,应仅读取先验值以确定要存储的值”可能是什么意思。 【参考方案1】:

a[i++] = 1 已定义(除非除了副作用的顺序之外还有其他未定义的原因:越界访问或未初始化的i)。

您的意思是a[i++] = i,这是未定义的行为,因为它在与i++ 相同的序列点之间读取i,这会改变它。

“此外,应仅读取先前值以确定要存储的值”部分表示允许i = i + 1;,尽管它从i读取并修改了i

另一方面,a[i] = (i=1); 是不允许的,因为尽管只向i 写入一次,但从i 读取的内容并不是为了计算要存储的值。

【讨论】:

【参考方案2】:

“应仅读取先验值以确定要存储的值”的措辞无疑是违反直觉的;为什么读取值的目的很重要?

这句话的重点是要求哪些结果取决于哪些操作。

我会从 Pascal's answer 那里窃取示例。

这个:

i = i + 1;

完全没问题。 i 在同一个表达式中读取和写入,没有中间序列点,但没关系,因为直到读取完成后才能进行写入。在表达式 i + 1 及其子表达式 i 被完全计算之前,无法计算要存储的值。 (并且i + 1 没有可能延迟到写入之后的副作用。)这种依赖性强加了严格的顺序:必须在写入开始之前完成读取。

另一方面,这个:

a[i] = (i=1);

具有未定义的行为。子表达式a[i]读取i的值,子表达式i=1写入i的值。但是写入存储在i 中的值不依赖于左侧读取i 的评估,因此没有定义读取和写入的顺序。 “要存储的值”是1;读取a[i] 中的i 并不能确定该值。

我怀疑这种混淆是 ISO C 标准 2011 年修订版(以 N1570 的草案形式提供)重新措辞该部分的原因。标准还是有序列点的概念,但是6.5p2现在说:

如果标量对象的副作用相对于其中任一对象而言是未排序的 对同一标量对象或值的不同副作用 使用相同标量对象的值进行计算,行为是 不明确的。如果有多个允许的排序 表达式的子表达式,如果这样的表达式的行为是未定义的 任何排序都会出现未排序的副作用。

第 1 段明确说明了仅在 C99 中隐含的假设:

运算符的操作数的值计算是有序的 在算子结果的值计算之前。

第 5.1.2.3 节第 2 段解释了 sequenced beforesequenced after 关系。

【讨论】:

我对@9​​87654338@ 感到困惑是否意味着b = a++; 意味着a 的增量发生在a++ 评估为a 之前? @ajay: 不。a++ 做了两件事:它计算一个值(比 a 的前一个值大 1),它具有修改 a 的副作用。副作用不是“价值计算”的一部分。赋值对b的修改只有在确定a++产生的值之后才能发生,但是赋值对b的修改和++a的修改可能发生在顺序(或并行)。

以上是关于我看不懂C99中的一些句子的主要内容,如果未能解决你的问题,请参考以下文章

apache和iis共用端口怎么弄啊?搜的东西我看不懂,有谁可以qq:519963851,多谢!!!

收藏 | 15 个你非了解不可的 Linux 特殊字符,妈妈再也不用担心我看不懂这些符号了!

css 背景background属性的简写我看不懂意思?

java for循环怎样写出1-10!的和啊,求详细说明,我看不懂

这是一段LCD12864液晶的其中一段C语言编程,我看不懂,其中的意思可以告诉我吗?哪怕一

看不懂英文怎么办!学习编程,英语对初学者很重要吗?