Date: Mon, 11 Oct 2021 17:47:33 -0400
> On Oct 11, 2021, at 4:06 PM, Richard Smith via Core <core_at_[hidden]> wrote:
>
> +SG12 for UB / object model question.
>
> On Sun, Oct 10, 2021 at 4:27 AM Andrey Erokhin <language.lawyer_at_[hidden] <mailto: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.
+1, but can we call it (“angelic nondeterminism”) something else ;-) ? Maybe “retroacted nondeterminism”?
I haven’t thought about the consequences for constexpr evaluation yet, but it’s not giving me the warm-and-fuzzies...
Daveed
> 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.
>
> 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.)
> _______________________________________________
> Core mailing list
> Core_at_[hidden] <mailto:Core_at_[hidden]>
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/core <https://lists.isocpp.org/mailman/listinfo.cgi/core>
> Link to this post: http://lists.isocpp.org/core/2021/10/11627.php <http://lists.isocpp.org/core/2021/10/11627.php>
>
> +SG12 for UB / object model question.
>
> On Sun, Oct 10, 2021 at 4:27 AM Andrey Erokhin <language.lawyer_at_[hidden] <mailto: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.
+1, but can we call it (“angelic nondeterminism”) something else ;-) ? Maybe “retroacted nondeterminism”?
I haven’t thought about the consequences for constexpr evaluation yet, but it’s not giving me the warm-and-fuzzies...
Daveed
> 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.
>
> 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.)
> _______________________________________________
> Core mailing list
> Core_at_[hidden] <mailto:Core_at_[hidden]>
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/core <https://lists.isocpp.org/mailman/listinfo.cgi/core>
> Link to this post: http://lists.isocpp.org/core/2021/10/11627.php <http://lists.isocpp.org/core/2021/10/11627.php>
Received on 2021-10-11 16:47:37