来自§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++;
显示未定义的行为,我如何证明这两个副作用是无效的?
答案 0 :(得分:6)
首先,如果A在B之前没有排序,B在A之前没有排序,则A和B 未排序(1.9 / 13)。这是未经测序的定义。其次,如果对标量对象的两个副作用未被排序,则行为未定义(1.9 / 15)。因此,除非你能找到一些说明后增量和赋值顺序的内容(并且你赢了),否则行为是未定义的。