对于前pressions定义的行为 [英] Defined behaviour for expressions

查看:156
本文介绍了对于前pressions定义的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C99标准说,在$ 6.5.2。

The C99 Standard says in $6.5.2.

在previous和下一个序列点的对象应具有其存储的值之间
  由前pression的评价最多一次修改。此外,前一个值
   应仅被理解为确定值存储到

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.

(由我强调)

它接着注意,下面的例子是有效的(这在第一似乎是显而易见的)

It goes on to note, that the following example is valid (which seems obvious at first)

a[i] = i;

虽然它没有明确说明是什么 A I

虽然我相信这不,我想知道这个例子是否涵盖以下情况:

Although I believe it does not, I'd like to know whether this example covers the following case:

int i = 0, *a = &i;
a[i] = i;

这会的的修改 i的值,但访问的值 I 确定地址放在哪里值。或者是不相关的,我们分配一个值 I 这已经存储在 I ?请提供一些线索。

This will not change the value of i, but access the value of i to determine the address where to put the value. Or is it irrelevant that we assign a value to i which is already stored in i? Please shed some light.

奖金问题;什么 A [I] ++ A [i] = 1

推荐答案

第一句:

在previous和下一个序列点的对象应具有其之间
  存储的值由前pression的评价最多一次修改。

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.

是清楚。语言没有对SUBEX pressions评价的命令,除非有它们之间的序列点,而不是要求的部分的评估未指定的顺序,它说,修改一个对象两次将产生不确定行为。这允许激进优化,同时还使其能够写code遵循的规则。

is clear enough. The language doesn't impose an order of evaluation on subexpressions unless there's a sequence point between them, and rather than requiring some unspecified order of evaluation, it says that modifying an object twice produces undefined behavior. This allows aggressive optimization while still making it possible to write code that follows the rules.

下一句:

此外,应仅读出的先前值,以确定该值被存储到

Furthermore, the prior value shall be read only to determine the value to be stored

似乎不直观的第一(和第二)一目了然;为什么要为它的值被读取的目的影响一个前pression是否已定义的行为?

does seem unintuitive at first (and second) glance; why should the purpose for which a value is read affect whether an expression has defined behavior?

但它反映的是,如果一个SUBEX pression B依赖于一个SUBEX pression A的结果,那么就必须评估的的B能进行评估。该C90和C99标准没有明确说明这一点。

But what it reflects is that if a subexpression B depends on the result of a subexpression A, then A must be evaluated before B can be evaluated. The C90 and C99 standards do not state this explicitly.

有一个更清晰的侵犯的那句话,在脚注中的例子给出的是:

A clearer violation of that sentence, given in an example in the footnote, is:

a[i++] = i; /* undefined behavior */

假设 A 是一个声明数组对象和 I 是一个声明整数对象(没有指针或宏挂羊头卖狗肉),没有对象被修改一次以上,所以它不违反第一句。但评估我++ 在LHS确定哪个对象被修改,和对RHS评价我确定将被存储在该对象中的值 - 没有定义和在RHS和在LHS写操作的读操作的相对顺序。再次,语言可能需要SUBEX pressions在一些未指定的顺序进行评估,而是它留下的整个行为都是不确定的,以允许更多积极的优化。

Assuming that a is a declared array object and i is a declared integer object (no pointer or macro trickery), no object is modified more than once, so it doesn't violate the first sentence. But the evaluation of i++ on the LHS determines which object is to be modified, and the evaluation of i on the RHS determines the value to be stored in that object -- and the relative order of the read operation on the RHS and the write operation on the LHS is not defined. Again, the language could have required the subexpressions to be evaluated in some unspecified order, but instead it left the entire behavior undefined, to permit more aggressive optimization.

在您的例子:

int i = 0, *a = &i;
a[i] = i; /* undefined behavior (I think) */

I 阅读既要确定该值将被存储的的决定previous值对象这将是存储在由于 A [I] I (但只是因为我== 0 ),修改 i的值将改变对象,该左值 A [I] 引用。它发生在这种情况下,存储在 i的值是相同的一个已经存储在那里的​​值( 0 ),但标准不会使这种情况发生,以存储相同值存储异常。我相信行为是不确定的。 (当然,在标准的例子的目的不是为了掩盖这种情况下,它隐含的假设是 A 是一个声明数组对象无关 I

the previous value of i is read both to determine the value to be stored and to determine which object it's going to be stored in. Since a[i] refers to i (but only because i==0), modifying the value of i would change the object to which the lvalue a[i] refers. It happens in this case that the value stored in i is the same as the value that was already stored there (0), but the standard doesn't make an exception for stores that happen to store the same value. I believe the behavior is undefined. (Of course the example in the standard wasn't intended to cover this case; it implicitly assumes that a is a declared array object unrelated to i.)

至于该标准说是允许的示例:

As for the example that the standard says is allowed:

int a[10], i = 0; /* implicit, not stated in standard */
a[i] = i;

有一个可以的跨preT标准地说,这是不确定的。但我认为,第二句,指的是以前的值,仅适用于年代由前pression修改对象的值。 I 永远不会被前pression修改,所以没有冲突。 I 既用来确定对象的值与分配进行修改,并且该值被存储在那里,但没关系,因为<$ c的值$ C> I 本身永远不会改变。的 I 的值不是事先值,它只是值。

one could interpret the standard to say that it's undefined. But I think that the second sentence, referring to "the prior value", applies only to the value of an object that's modified by the expression. i is never modified by the expression, so there's no conflict. The value of i is used both to determine the object to be modified by the assignment, and the value to be stored there, but that's ok, since the value of i itself never changes. The value of i isn't "the prior value", it's just the value.

在C11标准有这种前pression评价的新模式 - 或者更确切地说,它的前presses在不同的词相同的模型。而不是序列点,它谈论之前或彼此,或者unsequenced相对于彼此后被测序副作用。它使明确的想法,如果SUBEX pression B依赖于一个SUBEX pression A的结果,那么就必须评估的的B能进行评估。

The C11 standard has a new model for this kind of expression evaluation -- or rather, it expresses the same model in different words. Rather than "sequence points", it talks about side effects being sequenced before or after each other, or unsequenced relative to each other. It makes explicit the idea that if a subexpression B depends on the result of a subexpression A, then A must be evaluated before B can be evaluated.

的N1570 草案,第6.5节说:

In the N1570 draft, section 6.5 says:

1的的前pression 的是运营商和操作数的序列
      指定值的计算,或者,指定一个对象
      或函数,或产生副作用,或执行
      它们的组合。操作数的值计算
      操作者的所述值计算之前进行测序
      操作的结果。

1 An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof. The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.

2如果一个标物体上的副作用是相对于unsequenced
      无论是同一个标对象或在不同的副作用
      使用同一个标量对象的值值计算,
      行为是不确定的。如果有多个容许序
      一个前pression的SUBEX pressions的,其行为是未定义
      如果在任何的排序的发生这样的unsequenced副作用

2 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.

3运算和操作数的分组是由句法指示。
      除非指定后,副作用和价值计算
      SUBEX的pressions是unsequenced。

3 The grouping of operators and operands is indicated by the syntax. Except as specified later, side effects and value computations of subexpressions are unsequenced.

这篇关于对于前pressions定义的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆