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?
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?
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.
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
}
© 2022 - 2024 — McMap. All rights reserved.