C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::launder when multiple objects of the same type exist at the same address

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 17 Dec 2025 09:11:07 +0000
On Wed, 17 Dec 2025, 08:35 Tiago Freire via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> It is physically impossible for 2 distinct object to share the same
> address at the same time unless they have 0 size (i.e. unless there is no
> object, at which point address is irrelevant).
>

Can you restate this in terms of the C++ standard, e.g. potentially
overlapping subjects?


You can have 2 distinct pointers to the same address, pointing to the same
> object, but where the pointers can misrepresent the type of the object.
>
> An object is an abstract representation of a "thing", while the "pointer
> type" is just a hint of what that "thing is".
> I can have a "chair" and place a label on it calling a "table", I can even
> put a vase on top of this thing that I've labeled "table", I can invite
> guests to have dinner using this "table", but it is still a chair, and you
> certainly don't have both a distinct "table" and a "chair".
>

This doesn't seem relevant to the original mail.




>
> -----Original Message-----
> From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of
> Halalaluyafail3 via Std-Proposals
> Sent: Wednesday, December 17, 2025 02:40
> To: Halalaluyafail3 via Std-Proposals <std-proposals_at_[hidden]>
> Cc: Halalaluyafail3 <luigighiron_at_[hidden]>
> Subject: [std-proposals] std::launder when multiple objects of the same
> type exist at the same address
>
> N5032 Section 17.6.5 [ptr.launder] Paragraphs 2 and 3:
> > Preconditions: p represents the address A of a byte in memory. An
> > object X that is within its lifetime (6.8.4) and whose type is similar
> > (7.3.6) to T is located at the address A. All bytes of storage that
> > would be reachable through
> > (6.9.4) the result are reachable through p.
> >
> > Returns: A value of type T* that points to X.
>
> This section seems to assume that at most one possible X can exist.
> However, it appears possible to construct two objects in a way that they
> could both be that
> X:
>
> struct S{
> unsigned char x[4];
> };
> static_assert(sizeof(S)==4);
> S s;
> S*p=::new((void*)s.x)S;
> std::launder((S*)s.x)->~S();
> s.~S();
>
> All pointers involved here can reach all 4 bytes of s, so reachability
> doesn't affect anything. s is an object of type S which exists at some
> address A. An array s.x spanning all of the bytes of s exists as a
> subobject of s. s.x must have the same address as s because it occupies the
> same storage, and because of pointer-interconvertibility. Then, another
> object of type S is created in s.x where s.x provides storage for it. This
> new object *p occupies the same storage as s.x, so it must have the same
> address as s.x and s. So there are two objects s and *p which both have the
> same address, same type, same reachable bytes, and are both within their
> lifetime.
>
> Given this, it is unclear what std::launder((S*)s.x) points to. (S*)s.x
> points to the same address as both s and *p, and both objects meet the
> requirements to be X. Here is an example that demonstrates each case
> individually:
>
> //same S as before
> alignas(S)unsigned char a[4];
> ::new((void*)a)S;
> std::launder((S*)a)->~S();
> S b;
> std::launder((S*)b.x)->~S();
>
> std::launder((S*)s.x) could be either case, so is s.~S() defined (launder
> results in p) or undefined (launder results in &s)?
>
> See also GCC bug 121180, this issue can arise from types such as std::any
> which store objects internally if they are small enough. Specifically, an
> empty class can be stored in a std::any object and the std::any object can
> overlap with another object that has the same empty class type just right
> to cause both empty classes to have the same address.
>
> I'm thinking about making a LWG issue for this. Though I don't think any
> implementations implement these incorrectly because this overlapping
> requires the storage to be unused and cannot happen in constant expressions.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-12-17 09:11:25