0

I always thought that when I converted a member function ptr in C to a member function ptr in A, I just had to make sure that the call was pointing to an C entity , but that was a mistake. Does the standard describe this use case in more detail?(checked with multiple compilers,MSVC GCC error,clang pass,This could be a compiler bug or undefined behavior?)

struct A
{
    char i[7];
    void test1(){
        std::cout << __LINE__;
    }
};

struct B
{
    char i[14];
    virtual void test(){
        std::cout << __LINE__;
    }
};

struct C:A,B
{
    char i[31];
};

using T = void (C::*)();

int main()
{
    C c;
    (c.*T(&B::test))();//good
    (c.*static_cast<decltype(&A::test1)>(T(&B::test)))();//crash
    return 0;
} 
14
  • 2
    The standard does not describe ill-formed programs. warning C4407: cast between different pointer to member representations, compiler may generate incorrect code.
    – 3CxEZiVlQ
    Commented Dec 14, 2024 at 23:18
  • @3CxEZiVlQ In other words, even if I can guarantee that a base class pointer points to a derived class instance, is the upward conversion of member function pointers still dangerous?
    – 余国良
    Commented Dec 14, 2024 at 23:22
  • &A::test1 is not an "address". You code smells like the ill-formed code char c = 'a'; int* p = static_cast<int*>(static_cast<void*>(&c)); *p = 0;.
    – 3CxEZiVlQ
    Commented Dec 14, 2024 at 23:30
  • @3CxEZiVlQ I am just using it for type deduction. I previously wrote some other test cases, but in this test case, I don't want function overriding to occur, so I added a suffix.
    – 余国良
    Commented Dec 14, 2024 at 23:37
  • &B::test is a pointer-to-member-of-B. You can convert it, with a cast, into a pointer-to-member-of-A, even though B::test is not a member of A, but you cannot use the result of that cast without converting it back to its original type. Commented Dec 14, 2024 at 23:42

0

Browse other questions tagged or ask your own question.