简体   繁体   English

我无法理解C99中的一些句子

[英]I can not understand some sentences in C99

In C99 6.5 says: 在C99 6.5中说:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. 在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 Furthermore, the prior value shall be read only to determine the value to be stored 此外,先前的值应该只读以确定要存储的值

What does "Furthermore, the prior value shall be read only to determine the value to be stored" mean? 什么“此外,先前的值只能读取以确定要存储的值”是什么意思? In C99, why a[i++] = 1 is undefined behavior? 在C99中,为什么a[i++] = 1是未定义的行为?

a[i++] = 1 is defined (unless it has other reasons to be undefined than the sequencing of side-effects: out of bound access, or uninitialized i ). a[i++] = 1被定义(除非其他原因未定义,而不是副作用的排序:超出限制的访问,或未初始化的i )。

You mean a[i++] = i , which is undefined behavior because it reads i between the same sequence points as i++ , which change it. 你的意思a[i++] = i ,这是未定义的行为,因为它在与i++相同的序列点之间读取i ,这改变了它。

The “Furthermore, the prior value shall be read only to determine the value to be stored” part means that i = i + 1; “此外,先前的值应只读以确定要存储的值”部分表示i = i + 1; is allowed, although it reads from i and modifies i . 是允许的,虽然它从i读取并修改i

On the other hand, a[i] = (i=1); 另一方面, a[i] = (i=1); isn't allowed, because despite writing to i only once, the read from i is not for computing the value being stored. 是不允许的,因为尽管写i只有一次,从读i不是计算值被存储。

The "prior value shall be read only to determine the value to be stored" wording is admittedly counterintuitive; “先前的值应该只读以确定要存储的值”,措辞无疑是违反直觉的; why should the purpose for which a value is read matter? 为什么值的读取目的是什么?

The point of that sentence is to impose a requirement for which results depend on which operations. 该句的要点是强制要求哪些结果取决于哪些操作。

I'll steal examples from Pascal's answer . 我会从帕斯卡的答案中偷走一些例子。

This: 这个:

i = i + 1;

is perfectly fine. 很好。 i is read and written in the same expression, with no intervening sequence point, but it's ok because the write cannot occur until after the read has completed. i在相同的表达式中读取和写入,没有中间序列点,但是没关系,因为写入在读取完成之后才能发生。 The value to be stored cannot be computed until the expression i + 1 , and its subexpression i , have been completely evaluated. 在表达式i + 1及其子表达式i已被完全评估之前,不能计算要存储的值。 (And i + 1 has no side effects that might be delayed until after the write.) That dependency imposes a strict ordering: the read must be completed before the write can begin. (并且i + 1没有可能在写入之后延迟的副作用。)该依赖性强加了严格的排序:必须在写入开始之前完成读取。

On the other hand, this: 另一方面,这个:

a[i] = (i=1);

has undefined behavior. 有未定义的行为。 The subexpression a[i] reads the value of i , and the subexpression i=1 writes the value of i . 子表达式a[i] 读出的值i ,和子表达式i=1 写入的值i But the value to be stored in i by the write does not depend on the evaluation that reads i on the left hand side, and so the ordering of the read and the write are not defined. 但是通过写入存储在i的值不依赖于在左侧读取i的评估,因此未定义读取和写入的顺序。 The "value to be stored" is 1 ; “要存储的值”是1 ; the read of i in a[i] does not determine that value. a[i]中读取i并不能确定该值。

I suspect this confusion is why the 2011 revision of the ISO C standard (available in draft form as N1570 ) re-worded that section. 我怀疑这种混淆是为什么2011年修订的ISO C标准(草案形式为N1570 )重新措辞了该部分。 The standard still has the concept of sequence points , but 6.5p2 now says: 该标准仍然具有序列点的概念,但6.5p2现在说:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. 如果相对于对同一标量对象的不同副作用或使用相同标量对象的值进行值计算,对标量对象的副作用未被排序,则行为未定义。 If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings. 如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的。

And paragraph 1 states explicitly what was only implicitly assumed in C99: 第1段明确说明了C99中隐含的假设:

The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. 在运算符的结果的值计算之前,对运算符的操作数的值计算进行排序。

Section 5.1.2.3 paragraph 2 explains the sequenced before and sequenced after relationships. 第5.1.2.3节第2节解释了之前顺序和关系之后顺序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM