C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::polyhandle (Draft Paper Attached)

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Tue, 10 Jun 2025 10:59:41 +0100
On Tue, Jun 10, 2025 at 10:30 AM Frederick Virchanza Gotham wrote:
>
> I'm taking a look at two ABI's here: The Itanium ABI and the Microsoft
> ABI, to see what can be made possible in both.


As I said in a previous post, the address of the vtable pointer inside
a polymorphic object will always be divisible by alignof(void*),
meaning that the lower 3 bits are fair game to be used for storing
information So I'm thinking I'll use one of those bits to indicate if
the type has a virtual destructor, something like:

    template<class Tref> requires is_polymorphic_v< remove_cvref_t<Tref> >
    constexpr std::polyhandle(Tref &&obj) noexcept
    {
        typedef remove_cvref_t<Tref> T;
        this->p = const_cast<T*>( addressof(obj) );
        uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
        assert( 0u == (n % sizeof(void*)) );
        n |= std::has_virtual_destructor_v<T>;
        this->p = reinterpret_cast<void*>(n);
    }

And from there I'll try figure out if either the Itanium ABI or the
Microsoft ABI has a way of finding the destructor's address in the
vtable (unfortunately it's not always in the first position in the
vtable -- not even on Itanium). But if can figure out a way to find
the destructor in the vtable, then I could give 'polyhandle' another
method called 'destroy', something like:

    void std::polyhandle::destroy(void)
    {
        uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
        assert( n & 1u ); // ensure had virtual destructor
        n -= 1u;
        void *const ptr = reinterpret_cast<void*>(n);
        void (*const pf)(void*) = FindDestructorAddress(ptr); // Get from ABI
        assert( nullptr != pf );
        pf( this->most_derived() );
    }

Received on 2025-06-10 09:59:53