为什么内置类型的链式前缀 increment/decrement 不是 C++ 的 UB?

Why chained prefix increment/decrement for builtin type is not UB for C++?

在cpprefernce.com example中对于前缀增量有这样的代码:

int n1 = 1;
...
int n3 = ++ ++n1;

为什么这种情况下的链式递增不会导致UB?在这种情况下是否不违反最多修改一次的规则?

请参阅 答案了解更简单的术语,.

这是合法的,因为 C++ 标准是这样说的,重点是我的...遵循 C++14 草案

5.3.2 自增自减[expr.pre.incr]

The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field. If x is not of type bool, the expression ++x is equivalent to x+=1

所以,这是完全合法的

#include <iostream>
using namespace std;

int main(){
    int x =8;
    int y = ++ ++ ++ ++ ++ ++ ++ ++ x;
    cout << x << " " << y;

}

输出

16 16

1.9 程序执行 [intro.execution]

15...If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. ...

附上示例:

void f(int, int);
void g(int i, int* v) {
i = v[i++]; // the behavior is undefined
i = 7, i++, i++; // i becomes 9
i = i++ + 1; // the behavior is undefined
i = i + 1; // the value of i is incremented
f(i = -1, i = -1); // the behavior is undefined
}

在 C++11 及更高版本中,当有两次写入或一次写入和一次读取未按顺序访问同一内存位置时,就会出现 UB。但是++x等价于x+=1,所以++ ++n1等价于(n1+=1)+=1,由于赋值和复合赋值的特性,这里的读写是严格顺序的运算符:首先读取 n1,然后写入原始值加一,然后再次读取结果值,然后写回该值加一。

在C++03中,这个 UB,因为你提到的旧规则:两次修改之间没有序列点。但在 C++11 中不再有任何序列点;取而代之的是 "sequenced before" 偏序。