C++ Logo

std-discussion

Advanced search

Re: CWG710 and races during object construction

From: Jason Cobb <jason.e.cobb_at_[hidden]>
Date: Thu, 11 Feb 2021 13:05:41 -0500
On 2/11/21 12:56 PM, Giuseppe D'Angelo via Std-Discussion wrote:
> Hi,
>
> CWG710 deals with races during object construction (and similarly
> destruction):
>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#710
> The concern raised was about races on the virtual table itself, for
> instance by placing calls to virtual functions during an object's
> construction or destruction from another thread than the one
> constructing/destroying the object.
>
>
> The resolution for it added this paragraph to basic.life:
>
>> https://eel.is/c++draft/basic.life#11
>> In this subclause, “before” and “after” refer to the “happens before” relation ([intro.multithread]).
>> [Note: Therefore, undefined behavior results if an object that is being constructed in one thread is referenced from a different thread without adequate synchronization. —end note]
>
>
> It's not however clear to me how this resolution makes behaviour
> undefined in something like:
>
>> struct B {
>> B() {
>> std::thread t([&]() { typeid(*this); });
>> #if DETACH
>> t.detach(); // 1
>> #else
>> t.join(); // 2
>> #endif
>> }
>> virtual ~B();
>> };
>>
>> struct D : B {
>> ~D();
>> };
>>
>> D d;
> Is 1) UB, and 2) well formed (yielding B's type info)? "In practice"
> they are, but I'm just failing to find the right wording in the Standard
> that would express this.
>
> As far as I can see, this isn't a data race: the vtable and all the
> related RTTI information are just magical "metadata" [1] and thus
> doesn't participate in data races (which by definition involve memory
> locations [2][3], and memory locations are objects or bitfields [4], not
> the "metadata").
>
> [1] https://eel.is/c++draft/basic.memobj#intro.object-1.sentence-9
> [2] https://eel.is/c++draft/intro.multithread#intro.races-21.sentence-2
> [3] https://eel.is/c++draft/intro.multithread#intro.races-2.sentence-1
> [4] https://eel.is/c++draft/intro.memory#3.sentence-1
>
>
> I planned to raise a language defect, but then I stumbled into CWG710
> and thus wanted to ask for some guidance. What am I missing?


I think [0] has you covered for UB in case 1. The typeid does not
happen-before the destruction of the global, so it's UB to pass the
glvalue to typeid.


[0]: https://eel.is/c++draft/basic.life#7.4

-- 
Jason Cobb

Received on 2021-02-11 12:05:46