struct A{int a; A():a(1){}}
std::atomic<A*> x;
// thread 1:
A* ptr = new A(); // #1
x.store(ptr,memory_order::relaxed);
//thread 2:
auto ptr = x.load(memory_order::relaxed);
int b = ptr->a; // #2
intro.races p21 says:
Two actions are potentially concurrent if
- they are performed by different threads, or
- […]
The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other,
intro.races p2 defines what two conflict actions are
Two expression evaluations conflict if one of them modifies a memory location ([intro.memory]) and the other one reads or modifies the same memory location.
First, the evaluations at #1
and #2
neither happen before the other, and #1
is not atomic, #2
is a read to A::a
in the memory pointed to by ptr
. However, are they conflict actions? It’s unclear.
I don’t find wording in the standard that would say the initialization of an object is considered a modification to a memory location. How to interpret this example in terms of C++ standard?