Question

It looks like std::cout can't print member function's address, for example:

#include <iostream>

using std::cout;
using std::endl;

class TestClass
{
  void MyFunc(void);

public:
  void PrintMyFuncAddress(void);
};

void TestClass::MyFunc(void)
{
  return;
}

void TestClass::PrintMyFuncAddress(void)
{
  printf("%p\n", &TestClass::MyFunc);
  cout << &TestClass::MyFunc << endl;
}

int main(void)
{
  TestClass a;

  a.PrintMyFuncAddress();

  return EXIT_SUCCESS;
}

the result is something like this:

003111DB
1

How can I print MyFunc's address using std::cout?

Was it helpful?

Solution

I don't believe that there are any facilities provided by the language for doing this. There are overloads for operator << for streams to print out normal void* pointers, but member function pointers are not convertible to void*s. This is all implementation-specific, but typically member function pointers are implemented as a pair of values - a flag indicating whether or not the member function is virtual, and some extra data. If the function is a non-virtual function, that extra information is typically the actual member function's address. If the function is a virtual function, that extra information probably contains data about how to index into the virtual function table to find the function to call given the receiver object.

In general, I think this means that it's impossible to print out the addresses of member functions without invoking undefined behavior. You'd probably have to use some compiler-specific trick to achieve this effect.

Hope this helps!

OTHER TIPS

I'd like to add to the other answers, that the reason that you are getting '1' printed instead of an address, is that, for some reason, the compiler is coercing your function pointer into a boolean, so that you are really calling ostream& operator<< (bool val);

This seems to be unrelated to the function being a member function.

You can uncover this kind of information with clang++ -cc1 -ast-dump:

(ImplicitCastExpr 0x3861dc0 <col:13, col:25> '_Bool' <MemberPointerToBoolean>
    (UnaryOperator 0x3861940 <col:13, col:25> 'void (class TestClass::*)(void)' prefix '&'
        (DeclRefExpr 0x38618d0 <col:14, col:25> 'void (void)' CXXMethod 0x3861500 'MyFunc' 'void (void)')))))

One way to do that is (I'm not sure it's portable) :

void TestClass::PrintMyFuncAddress(void)
{
  void (TestClass::* ptrtofn)() = &TestClass::MyFunc;
  cout << (void*&)ptrtofn<< endl;
}

working example : http://ideone.com/1SmjW

Pointers to member functions need memory, too. They also have a size. So how about printing out the memory of the pointer:

template<typename R, typename T, typename... Args>
std::string to_string(R (T::*func)(Args...))
{
    union PtrUnion
    {
        R(T::*f)(Args...);
        std::array<unsigned char, sizeof(func)> buf;
    };
    PtrUnion u;
    u.f = func;

    std::ostringstream os;

    os << std::hex << std::setfill('0');
    for (auto c : u.buf)
        os << std::setw(2) << (unsigned)c;

    return os.str();
}

You can use it this way:

class TestClass
{
    void foo();
};

...

std::cout << to_string(&TestClass::foo) << std::endl;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top