The standard states that the behavior of unsequenced operations that have side effect on the same memory location is undefined [intro.execution§10].
Does the following code have undefined behavior, for having multiple unsequenced side effects on the variable sid, through the unsequenced call to bar in main:
int bar() {
static int sid;
return ++sid;
}
void foo(int i1, int i2) {
std::cout << i1 << std::endl;
std::cout << i2 << std::endl;
}
int main() {
foo(bar(), bar());
}
If the above has undefined behavior, would making sid an atomic<int>
, solve the issue and make the code valid?
int bar() {
static std::atomic<int> sid;
return ++sid;
}
And what about making it volatile
?
int bar() {
static volatile int sid;
sid += 1;
return sid;
}
Code to play with: https://godbolt.org/z/ob6scchaP
Does the following code have undefined behavior, for having multiple unsequenced side effects on the variable
sid
, through the unsequenced call tobar
inmain
According to https://www.cppreference.com/w/cpp/language/eval_order.html#Rules 10 (emphasis mine)
A function call that is not sequenced before or sequenced after another expression evaluation outside of the function (possibly another function call) is indeterminately sequenced with respect to that evaluation (the program must behave as if the CPU instructions that constitute a function call were not interleaved with instructions constituting evaluations of other expressions, including other function calls, even if the function was inlined).
So both call to function bar()
are indeterminately sequenced.
You don't have multiple unsequenced side effects on the variable sid
. No UBs.
So both outputs 1 2
or 2 1
are possible (and it can even change at each execution).
If the above has undefined behavior, [..]
That remains irrelevant.