> Actually I don't think your c++ program contains a data race, because the writes that populated the argument string happened before the atomic read
But the write to the static variable from the second thread is entirely unordered with respect to the read, despite the atomicity. If lack of ordering is your criterion for data races, doesn't that imply there is a data race between that write and that read?
No, because it's atomic. If that was a data race, and data races are UB, there would be no point in having relaxed atomics.
It's not my criterion, it's defined in the language standard. You can't have a data race on an atomic except for std::atomic_init. The reads on the string contents themselves are ordered because the args string is initialized before the thread is launched and the other one is static. If the launched thread allocated a new string and then populated the atomic, that would be a data race, unless stronger memory order was used by both the writer and the reader.
Never mind, I don't think we're disagreeing on what the C++ standard definition of data race is. I think I thought you were saying something different in your comment.