C++ Logo

std-proposals

Advanced search

Re: [std-proposals] consteval int relocatability

From: Oliver Hunt <oliver_at_[hidden]>
Date: Tue, 11 Nov 2025 23:45:28 -0800
> On Nov 11, 2025, at 11:04 PM, Lénárd Szolnoki <cpp_at_[hidden]> wrote:
>
>
>
> On 11 November 2025 23:33:42 GMT, Oliver Hunt via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>>
>>
>>> On Nov 11, 2025, at 6:34 AM, Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>
>>> On Mon, Nov 10, 2025 at 10:08 AM Oliver Hunt wrote:
>>>>
>>>> Re: funky - it would actually just be impossible, it is not defined
>>>> in a context where C++ exists, and it has no support for the C++
>>>> type system, hence it being invalid to use it over most C++ types.
>>>
>>>
>>> You’re absolutely right about `qsort` using ` void* ` and not having access
>>> to the C++ type system – I’d simply overlooked that.
>>>
>>> I have a question for you Oliver about `std::restart_lifetime` in the presence
>>> of arm64e pointer authentication.
>>>
>>> For the sake of argument, let's suppose that the compiler has a builtin
>>> function as follows:
>>>
>>> void const * __builtin_get_address_vtable(T);
>>>
>>> which, for a class type `T`, yields the address of the vtable.
>>>
>>> Then we could print the vtable address of 'std::ostream' as follows:
>>>
>>> #include <iostream>
>>> using namespace std;
>>> int main()
>>> {
>>> cout << __builtin_get_address_vtable(ostream) << endl;
>>> }
>>
>> This is essentially what copy constructors do - `__builtin_get_address_vtable` is a reference to the vtable symbol.
>>
>> The problem is that trivial relocation and restart lifetime are/were specified to maintain the dynamic type of the object, so you can’t simply store the vptr for the static type, but rather have to load the vptr from the object being relocated/restarted.
>
> You couldn't use trivial relocation on potentially overlapping subobjects, hence base subobjects. Which means you couldn't use it with not matching static and dynamic types in the first place.

I’m not sure what you mean here? You could relocate from one location to a potentially overlapping destination, and the semantics as specified maintained the dynamic type. E.g the functional behaviour - absent technologies like pointer authentication - was identical to memmove, this included the hazard of performing a relocation where the static type did not match the dynamic type, which could result in object slicing, and a host of problems the follow from that.

To my knowledge this was the intended behavior, as all arguments assumed that the behavior of TR without pointer auth was equivalent to memmove, but if it is expected to override the dynamic type of an object with the static type, then it is not longer memmove on _any_ implementation. I presumed that this worked on the assumption that a developer had guaranteed that when relocating with static type A, an object with dynamic type B is the same size and ABI as the super type A, which is certainly a thing that people do. If the intent in this scenario is to mimic a copy constructor and revert the dynamic type to the relocated static type, then TR requires similar logic to replace the dynamic type across all platforms, not just those with ptrauth, i.e. it would not be memmove anywhere.

—Oliver






Received on 2025-11-12 07:45:30