在C11前pressions赋值运算符测序 [英] Assignment operator sequencing in C11 expressions

查看:149
本文介绍了在C11前pressions赋值运算符测序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C11标准(ISO / IEC 9899:2011)日前推出副作用测序的新定义一个前pression内(<一个href=\"http://stackoverflow.com/questions/21066593/sequence-points-and-side-effects-quiet-change-in-c11\">see相关的问题)。在序列点的概念已经补充了的测序之前的和的测序后的关系,这是现在所有定义的基础。

The C11 standard (ISO/IEC 9899:2011) has introduced a new definition of side effect sequencing within an expression (see related question). The sequence point concept has been complemented with sequenced before and sequenced after relations which are now the basis for all definitions.

第6.5节前pressions,点2说:

Section 6.5 "Expressions", point 2 says:

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

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.

后来,节6.5.16赋值运算符,第3点规定:

Later on, section 6.5.16 "Assignment operators", point 3 states:

更新所述左操作数的存储值的副作用是左和右操作数的值计算后进行测序。的评价
  操作数unsequenced。

The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

第一个引用的段落(6.5 / 2)是由两个例子(同C99标准)的支持

第一个例子

Problem

The first quoted paragraph (6.5/2) is supported by two examples (same as in the C99 standard):

a[i++] = i;  //! undefined
a[i] = i;    //  allowed

这可以用定义来很容易解释:

This can be easily explained with the definitions:


  1. 如果一个标对象的副作用是相对于(......)使用相同的标量对象的值的值计算unsequenced,行为是不确定的。的(6.5 / 2),

  2. 操作数的评价是unsequenced。的[分配中(6.5.16 / 3)。

  1. If a side effect on a scalar object is unsequenced relative to (...) a value computation using the value of the same scalar object, the behavior is undefined. (6.5/2),
  2. The evaluations of the operands are unsequenced. [within an assignment] (6.5.16/3).

所以,副作用 i ++ (左)被unsequenced与 I (RHS),这给未定义行为。

So, the side effect of i++ (LHS) is unsequenced with i (RHS), which gives undefined behaviour.

i = ++i + 1; //! undefined
i = i + 1;   //  allowed

这code,然而,似乎是导致这两种情况下,给出一个定义的行为:

This code, however, seems to result in a defined behaviour in both given cases as:


  1. 更新所述左操作数的存储值的副作用是左和右操作数的值计算后进行测序。

  1. the side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands.

所以,执行 + I + 1
应precede更新的副作用 I ,这意味着不存在的上的标量对象unsequenced相对于任一不同的副作用的副作用上相同的标量对象或使用相同的标量对象的值的值的计算。

So, the execution of ++i + 1 shall precede the side effect of updating i, which means that there is not a side effect on a scalar object 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.

这是很容易解释与C99标准psented的术语和定义$ P $这些例子(的看到相关的问题)。但是,为什么是 I = + I + 1 根据C11的术语未定义?

It is easy to explain these examples with the terms and definitions presented by the C99 standard (see related question). But why is i = ++i + 1 undefined according to C11's terminology?

推荐答案

更新

在这里,我改变我的答案,这是没有很好地界定C11虽然是在C ++ 11。这里的关键是,结果 ++我不是左值,因此不需要在左值到右值转换++我进行评估,所以我们不能保证的结果++我将在后面读取。这是比C ++不同,所以我最初链接缺陷报告,在这个关键的事实铰链:

I am changing my answer here, this is not well defined in C11 although it is in C++11. The key here is that the result of ++i is not an lvalue and therefore does not require an lvalue-to-rvalue conversion after ++i is evaluated and so we can not be assured that the result of ++i will be read afterwards. Which is different than C++ and so the defect report I originally linked to hinges on this critical fact:

[...]左值前pression ++我,然后做的结果左值到右值的转换。保证了递增的副作用是在加法运算的计算之前测序[...]

[...] the lvalue expression ++i and then do an lvalue-to-rvalue conversion on the result. guarantees that the incrementation side-effect is sequenced before the computation of the addition operation[...]

我们可以进入到 C11草案看到这标准部分 6.5.3.1 preFIX增量和减量操作符的它说:

we can see this by going to the C11 draft standard section 6.5.3.1 Prefix increment and decrement operators which says:

[...]这位前pression + E是等于(E + = 1)。[...]

[...]The expression ++E is equivalent to (E+=1).[...]

和则第 6.5.16 赋值运算符的它说(的重点煤矿前进的):

and then section 6.5.16 Assignment operators which says (emphasis mine going forward):

赋值运算符存储在由左操作数所指定的对象的值。一个
  转让前pression有左操作数的值赋值, 111 之后,但不是左值即可。[...]

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111 but is not an lvalue.[...]

和脚注 111 说:

的实施允许读取对象,以确定该值,但不要求,即使当对象具有挥发性限定类型

The implementation is permitted to read the object to determine the value but is not required to, even when the object has volatile-qualified type.

有没有要求阅读对象,以确定它的价值,即使它是挥发性的。

There is no requirement to read the object to determine it's value even if it is volatile.

原来的答案

据我可以告诉这实际上是明确和这个例子是从它使用类似的语言C ++标准草案中删除。我们可以看到这 637。排序规则
和示例不同意
它说:

As far as I can tell this is actually well defined and this example was removed from the C++ draft standard which uses similar language. We can see this in 637. Sequencing rules and example disagree which says:

下面前pression仍被列为未定义行为的一个例子:

the following expression is still listed as an example of undefined behavior:

i = ++i + 1;


  
  

不过,现在看来,新的测序规则作出明确定义这个前pression:

However, it appears that the new sequencing rules make this expression well-defined:

和分辨率是罢工的preFIX例如,使用后缀例子,而不是这显然是不确定的:

and the resolution was to strike the prefix example and use the postfix example instead which is clearly undefined:

更改例如,在1.9 [intro.execution]第16段如下:

Change the example in 1.9 [intro.execution] paragraph 16 as follows:

我= ++ I 我++ + 1; //这种行为是未定义

i = ++i i++ + 1; // the behavior is undefined

这篇关于在C11前pressions赋值运算符测序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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