C++ Logo

STD-DISCUSSION

Advanced search

Subject: Re: CWG710 and races during object construction
From: Jason Cobb (jason.e.cobb_at_[hidden])
Date: 2021-02-11 12:05:41


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

STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups