C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Allow conversion of memfunc pointers to func pointers

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Tue, 16 Jan 2024 07:45:06 +0000
On Mon, Jan 15, 2024 at 1:57 AM Thiago Macieira via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> then the vtable linker symbol is
> > '_ZTV5Donkey'.
>
> And this one is _ZTV6Donkey.


Another possibility would be to get the vtable pointer from the
'std::type_info', as follows:

    template<class Class> requires std::is_polymorphic_v<Class>
    void (*const *GetVtable(void))(void)
    {
        // The type_info struct for T is located
        // right after the vtable for T.
        // The vtable for T contains a pointer to the type_info.
        // So take the address of the type_info struct,
        // and keep decrementing and dereferencing it until we
        // see the address of the type_info struct -- the vtable
        // is right after it.

        static constexpr void const *pv = &typeid(Class);
        static constexpr void const *const *ppv = static_cast<void
const *const *>(pv);

        for ( void const *const *p = ppv; ; --p )
        {
            if ( pv != *p ) continue;

            return
                static_cast<void(*const*)(void)>(
                    static_cast<void const*>(
                        static_cast<char const*>(
                            static_cast<void const*>(p)
                        ) - 0xe8
                    )
                );
        }
    }

I have it working here: https://godbolt.org/z/fe9Wd5EW1

I wonder if there will come a point when we should mention vtables in
the Standard? We don't have to call them vtables, maybe just call them
"polymorphic facilitators" or some other generic term that leaves the
door open for compiler implementers, and then we could get the vtable
pointer from the 'type_info' as follows:

    namespace std {
        class type_info {
            void const *get_polymorphic_facilitator(void) noexcept;
        };
    }

Let it return a nullptr if !std::is_polymorpic_v<T>.

Received on 2024-01-16 07:45:19