C++ Logo

sg12

Advanced search

Re: [SG12] Are we OK with objects which are subobjects of 2 (or more) objects at the same time?

From: Peter Sewell <Peter.Sewell_at_[hidden]>
Date: Tue, 12 Oct 2021 09:22:51 +0100
On Mon, 11 Oct 2021 at 21:08, Richard Smith via SG12 <sg12_at_[hidden]>
wrote:

> +SG12 for UB / object model question.
>
> On Sun, Oct 10, 2021 at 4:27 AM Andrey Erokhin <language.lawyer_at_[hidden]>
> wrote:
>
>> [intro.object]/2 says:
>> > If an object is created in storage associated with a member subobject
>> or array element /e/ (which may or may not be within its lifetime), the
>> created object is a subobject of /e/'s containing object if:
>> > — the lifetime of /e/'s containing object has begun and not ended, and
>> > — the storage for the new object exactly overlays the storage location
>> associated with /e/, and
>> > — the new object is of the same type as /e/ (ignoring cv-qualification).
>>
>> Now, lets look at
>>
>> struct S
>> {
>> std::byte m;
>>
>
> Let's imagine there's some more stuff here so sizeof(S) is larger:
>
> char padding[123];
> int align_to_int;
>
>
>> };
>>
>> std::byte buf[sizeof(S)];
>>
>> auto p = new (buf) S {}; //1
>> new (buf) std::byte{}; //2
>>
>
> If we continue this example:
>
> int *p = new (buf + sizeof(int)) int;
>
> ... then we know at this point the lifetime of S has ended because its
> storage was reused. So if the object created at //2 was a subobject of the
> S object created at //1, then that object is in a bad state -- it's a
> subobject of an object whose lifetime has ended. That sounds problematic --
> at least in principle -- for things that look like variant<S, std::byte>.
>
> So I think either we want to say that the newly-created object at //2 is a
> subobject of two different objects or we want to say that we use angelic
> nondeterminism here (//2 either creates a subobject of S, replacing s.m, or
> creates a subobject of buf, replacing buf[0], depending on how the program
> continues). Given that we already have angelic nondeterminsm in the object
> model and don't otherwise have cases where the subobject structure is not a
> tree, I think the angelic nondeterminism model would likely be the better
> option. That and, I don't think it's desirable to allow a newly-created
> object to be used as two different subobjects -- the program should not be
> engaging in such object identity punning.
>

I don't know all the C++ context here, but I expect that angelic
nondeterminism would be a nightmare for anyone trying to make the object
model precise, in tools or in maths. If at all possible, I'd suggest
finding some way to identify the lifetime end points (either implicitly or,
analogous to placement-new, with an explicit kill), so that one can
maintain an unambiguous tree-shaped subobject structure.

Peter



>
> A few words about //1: well, an object of std::byte type which is a
>> subobject corresponding to S::m NSDM is "created" there, but I don't think
>> [intro.object]/2 cares about it. So lets ignore line //1 here.
>>
>> In //2, however, the newly-created complete object of std::byte type
>> becomes both array element of buf and member subobject of *p, according to
>> [intro.object]/2. And I don't think this is what we want.
>>
>> What if we rewrite the rule as follows:
>> > If an object is created in storage associated with a member subobject
>> or array element /e/ (which may or may not be within its lifetime), the
>> created object is a subobject of /e/'s containing object <ins>/c/</ins> if:
>> > — the lifetime of <del>/e/'s containing object</del><ins>/c/</ins> has
>> begun and not ended, and
>> > — the storage for the new object exactly overlays the storage location
>> associated with /e/, and
>> > — the new object is of the same type as /e/ (ignoring
>> cv-qualification)<del>.</del><ins>, and</ins>
>> > <ins>— there is no member subobject or array element /e1/ and its
>> containing object /c1/ satisfying these constraints nested within /c/.</ins>
>>
>> Then, the newly-created complete object of std::byte type will only
>> become a member subobject of *p.
>>
>
> (Note from Andrey for SG12's benefit: *In the previous message, the word
> "complete" should be completely ignored.)
> _______________________________________________
> SG12 mailing list
> SG12_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg12
> Searchable archives: http://lists.isocpp.org/sg12/2021/10/index.php
>

Received on 2021-10-12 03:23:33