C++ Logo

std-proposals

Advanced search

Re: [std-proposals] dynamic_cast<void*>(void*)

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Mon, 26 Feb 2024 11:46:34 +0100
Does this work with multiple inheritance?   -----Ursprüngliche Nachricht----- Von:Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Mo 26.02.2024 11:22 Betreff:[std-proposals] dynamic_cast<void*>(void*) An:std-proposals <std-proposals_at_[hidden]>; CC:Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>; With regard to dynamic_cast'ing to a void*, the Standard currently reads:    7.6.1.7 Dynamic cast    1. The result of the expression dynamic_cast<T>(v) is       the result of converting the expression v to type T.    5. Otherwise, v shall be a pointer to or a glvalue of a       polymorphic type.    7. If T is “pointer to cv void”, then the result is a pointer       to the most derived object pointed to by v. So let's consider the following function:    void *Func(std::ostream *const v)    {        return dynamic_cast<void*>(v);    } On an x86_64 computer running Linux or macOS, using the GNU g++ compiler, this becomes:    test   rdi,rdi    je     the_pointer_is_null    mov    rax,QWORD PTR [rdi]    add    rdi,QWORD PTR [rax-0x10]    mov    rax,rdi    ret the_pointer_is_null:    xor    eax,eax    ret If we remove the code that allows for 'v' to be a nullptr, it's simplified further to:    mov    rax,QWORD PTR [rdi]    add    rdi,QWORD PTR [rax-0x10]    mov    rax,rdi    ret This assembler can be converted back into C++ as follows:    void *Func(void *const v)    {        auto const p_vtable = *static_cast<uintptr_t**>(v);        auto const top_offset = p_vtable[-2];        return static_cast<char*>(v) + top_offset;    } The implementation of this function is the same no matter what the type of 'v' is -- so long as it's a polymorphic type. In fact, it can be rewritten as follows:    void *Func(void *const v)    {        struct Dummy { virtual ~Dummy(void){} };        return dynamic_cast<void*>( static_cast<Dummy*>(v) );    } The point I want to make here is as follows: So long as 'v' points to a polymorphic type, it is not necessary to know that that type is. Therefore I think that the functionality of 'dynamic_cast' should be expanded to allow 'v' to be a pointer to void -- with the note that the behaviour is undefined if 'v' points to a non-polymorphic object. -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-02-26 10:46:35