x+=x*=x
是未定义的行为吗?14)对于不确定顺序的函数调用,复合赋值运算符的操作以及递增和递减运算符的前缀和后缀形式都是单个求值。
1)是。
C17 6.5.16赋值运算符,第3节
操作数的求值是无序列的。
由于C17 6.5§2而将其设为UB
如果相对于相同标量对象的不同副作用或使用相同标量对象的值进行的值计算,相对于标量对象的副作用未排序,则行为未定义。
每次分配都是副作用。 C99具有相同的规则,但更容易理解:
C99 6.5§2
在上一个和下一个序列点之间,对象应具有其存储的值通过对表达式的求值最多只能修改一次。此外,先验价值应该是只读的,以确定要存储的值。
2)所有具有C11排序更改的文本都很难阅读。他们使用未在任何地方正式定义的术语,例如“单一评估”。
规范性文本为C17 6.5.15.2§3
形式为E1 op = E2的复合赋值等同于简单赋值表达式E1 = E1 op(E2),除了左值E1仅被评估一次,且对于不确定顺序的函数调用,复合赋值的操作是单个求值。
我想这只是意味着像int x;
... x += 1
之类的操作应导致机器代码如下:
否则,假设某些东西在更新x
的那些操作之间获得了顺序。但是复合赋值不是原子的,所以我不太理解这里的标准。