C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Downcasting without Sidecasting

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Tue, 9 Jul 2024 15:33:06 +0100
On Tue, Jul 9, 2024 at 8:36 AM Frederick Virchanza Gotham wrote:
>
> I want to try code this. What compiler are you most interested in?
> VC++ / g++ / clang / icx ?


For the timebeing I'll go with GNU g++ on Linux x86_64. Starting out
with this code:

    struct Base { virtual ~Base(){} };
    struct Derived1 : Base { virtual ~Derived1(){} };
    struct Derived2 : virtual Base { virtual ~Derived2(){} };
    struct MostDerived : Derived1, virtual Derived2 {};

    MostDerived *Caster(Base *const p)
    {
        return dynamic_cast<MostDerived*>(p);
    }

I see that the function, 'Caster', gets compiled to:

          test rdi, rdi
          je Label
          mov rcx, -1
          mov edx, OFFSET FLAT:typeinfo for MostDerived
          mov esi, OFFSET FLAT:typeinfo for Base
          jmp __dynamic_cast
      Label:
          xor eax, eax
          ret

Let's look at what's put in the registers:

    RDI = Address of object
    RSI = Address of type_info for base
    RDX = Address of type_info for derived
    RCX = -1

So it looks like "__dynamic_cast" is a function with four parameters
and a signature as follows:

    void *__dynamic_cast(void *p, type_info const *base, type_info
const *derived, long long);

I did a search on Github just now and found the implementation here:

    https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/dyncast.cc#L45

Scroll down to Line #89 and you'll see the comment:

    // Both src and dst are known to be public bases of whole.
    // Found a valid cross cast.

And if you scroll down to Line #101, you'll see:

    // Found a valid down cast

So I reckon it's really just as simple as commenting out a few lines
in that function to achieve your 'dynamic_cast' that only does
downcasts.

Received on 2024-07-09 14:33:19