[new.delete.dataraces] states that calling "the library versions of
operator new" is not a data race. It then goes on to talk about memory
allocation and deallocation.
But placement-new doesn't do allocation. And I cannot imagine how
performing placement-new from different threads on the same storage
isn't a data race.
Now, if the new expression that invokes placement-new involves
initialization, then yes, that does cause a data race with other
initializing placement-new operations on that storage. This is because
of the initialization operations conflicting by accessing the same
And while we're here, `start_lifetime_as` doesn't seem to have any
language about data races. So like... what does that mean?
I think we're covered by [basic.life]/11. Placement new or std::start_lifetime_as ends the life of the other object by storage reuse, so if two threads use the same storage for objects potentially concurrently, that's a data race.
Std-Discussion mailing list