To preface, I do think this is a silly question but am confused about it.
I'm currently trying to understand the C++ memory model (particularly reordering with weaker order semantics) and have a question regarding the initialization of a shared variable before concurrent threads begin accessing it. So if I have a simple program like below, where I only want to increment an atomic counter using a relaxed memory order, everything runs fine.
#include <iostream>
using namespace std;
atomic<int> x{0};
void doWork(){
x.fetch_add(1, memory_order_relaxed);
}
int main()
{
thread t1(doWork());
thread t2(doWork());
t1.join();
t2.join();
cout << x.load(); << endl;
return 0;
}
However, if I initialize the atomic int x in the body of main as below:
#include <iostream>
using namespace std;
void doWork(atomic<int>& x){
x.fetch_add(1, memory_order_relaxed);
}
int main()
{
static atomic<int> x{0};
thread t1(doWork(ref(x)));
thread t2(doWork(ref(x)));
t1.join();
t2.join();
cout << x.load(); << endl;
return 0;
}
I'm not sure if this is safe code. In the case x wasn't an int but a more complex type, is it possible for the read-modify-write in either threads t1 or t2 to be reordered before the atomic x is fully initialized? I believe static initialization is thread safe, but since we use a relaxed memory order here and the initialization of x occurs inside the main program, does it still work "as intended"? And in this case, does using static make any difference since the initialization is meant to occur in the main program thread only once anyways?