Date: Wed, 17 Dec 2025 09:23:06 +0000
On Wed, 17 Dec 2025 at 09:11, Jonathan Wakely <cxx_at_[hidden]> wrote:
>
>
> 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?
>
*subobjects
(sorry, autocorrect)
>
>
> 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
>>
>
>
>
> 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?
>
*subobjects
(sorry, autocorrect)
>
>
> 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:23:26
