Search code examples
c++pointersmemorypointer-to-membernon-member-functions

Why member function address are so far away from free functions?


Taking this example: https://godbolt.org/z/gHqCSA

#include<iostream>

template<typename Return, typename... Args>
std::ostream& operator <<(std::ostream& os, Return(*p)(Args...) ) {
    return os << (void*)p;
}

template <typename ClassType, typename Return, typename... Args>
std::ostream& operator <<(std::ostream& os, Return (ClassType::*p)(Args...) )
{
    unsigned char* internal_representation = reinterpret_cast<unsigned char*>(&p);
    os << "0x" << std::hex;

    for(int i = 0; i < sizeof p; i++) {
        os << (int)internal_representation[i];
    }

    return os;
}
struct test_debugger { void var() {} };
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}

int main() {
    std::cout << "0. " << &test_debugger::var << std::endl;
    std::cout << "1. " << fun_void_void << std::endl;
    std::cout << "2. " << fun_void_double << std::endl;
    std::cout << "3. " << fun_double_double << std::endl;
}

// Prints:
//    0. 0x7018400100000000000
//    1. 0x100401080
//    2. 0x100401087
//    3. 0x100401093

I see the address of the member function is 0x7018400100000000000, which is understandable because member functions pointers have 16 bytes while free function as 0x100401080 have only 8 bytes.

However, why the member function address 0x7018400100000000000 is so far away from free function address 0x100401080? i.e., |0x7018400100000000000 - 0x100401080| = 0x70184000FFEFFBFEF80?

Why it is not closer i.e., something like 0x100401... instead of 0x701840...? Or I am printing the member function address wrong?


Solution

  • Your architecture is little-endian. The low byte of the address is in the first byte of p, so your address is being printed out backwards.