如何确定对作业的两个副作用是否未被排序?

时间:2016-02-01 17:25:18

标签: c++ language-lawyer c++17 partial-ordering

来自§5.2.6/1我们(强调是我的):

  

后缀++表达式的值是其操作数的值。 [   注意:获得的值是原始值的副本 - 结束注释]   操作数应是可修改的左值。操作数的类型   应该是cv bool以外的算术类型,或指向a的指针   完整的对象类型。操作数对象的值由。修改   加1吧。 ++表达式的值计算是   在修改操作数对象之前排序。同   关于一个不确定顺序的函数调用,操作   postfix ++是一个单一的评估。 [注意:因此,一个功能   呼叫不应介入左值到右值的转换和   与任何单个postfix ++运算符相关的副作用。 - 结束   注意]结果是prvalue。结果的类型是   cv-操作数类型的非限定版本。如果操作数是a   不能表示递增值的位字段,结果   位字段的值是实现定义的。另见[expr.add]   和[expr.ass]。

也就是说,操作数对象的修改在 ++表达式的值计算之后排序。

来自§5.18/1我们(强调是我的):

  

赋值运算符(=)和复合赋值运算符all   小组从右到左。所有都需要左侧可修改的左值   操作数并返回一个引用左操作数的左值。结果   在所有情况下,如果左操作数是位字段,则是位字段。在所有   例如,赋值在值计算之后排序   右边和左边的操作数,以及之前的值计算   赋值表达式。关于不确定的顺序   函数调用,复合赋值的操作是单一的   评价。 [注意:因此,函数调用不得介入   在左值到左值的转换和相关的副作用之间   使用任何单个复合赋值运算符。 - 结束说明]

     

赋值表达式
      条件表达式
       logical-or-expression assignment-operator initializer-clause
      套上表达

     

assignment-operator :中的一个       = * = / =%= + = - =>> =<< =& = ^ = | =

在赋值运算符的右和左操作数的值计算之后,赋值也排序。

因此,如果我们考虑表达式

i = i++;

我们从§5.2.6/ 1中知道,表达式i++对该赋值表达式的RHS的副作用在i++的值计算之后进行了排序。从§5.18/ 1我们知道,在赋值运算符的右和左操作数的值计算之后,对赋值运算符的LHS上赋值给i的副作用进行了排序。

但是为了证明表达式i = i++;显示未定义的行为,我如何证明这两个副作用是无效的?

1 个答案:

答案 0 :(得分:6)

首先,如果A在B之前没有排序,B在A之前没有排序,则A和B 未排序(1.9 / 13)。这是未经测序的定义。其次,如果对标量对象的两个副作用未被排序,则行为未定义(1.9 / 15)。因此,除非你能找到一些说明后增量和赋值顺序的内容(并且你赢了),否则行为是未定义的。