问题
In cpprefernce.com example for prefix increment there is such code:
int n1 = 1;
...
int n3 = ++ ++n1;
Why chained increment in this case does not lead to UB? Is rule for at most once modified not violated in this case?
回答1:
In C++11 and later, UB occurs when there are two writes or a write and a read that are unsequenced and access the same memory location. But ++x
is equivalent to x+=1
, so ++ ++n1
is equivalent to (n1+=1)+=1
, and here the reads and writes happen in a strict sequence because of the properties of assignment and compound assignment operators: first n1
is read, then one plus the original value is written, then the resulting value is read again, then one plus that value is written back.
In C++03, this was UB, because of the old rule you allude to: there is no sequence point between the two modifications. But in C++11 there are no longer any sequence points; instead there is the "sequenced before" partial order.
回答2:
See Brian's answer for simpler terms, .
It's legal cause the C++ standard says so, emphasis are mine... Going by the C++14 draft
5.3.2 Increment and decrement [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
So, this is perfectly legal
#include <iostream>
using namespace std;
int main(){
int x =8;
int y = ++ ++ ++ ++ ++ ++ ++ ++ x;
cout << x << " " << y;
}
Output
16 16
1.9 Program execution [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. ...
And it's attached example:
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
}
来源:https://stackoverflow.com/questions/35464793/why-chained-prefix-increment-decrement-for-builtin-type-is-not-ub-for-c