If you turn on the warnings (pass the -Wall
flag to the compiler), the compiler will tell you what you are doing wrong:
warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int (B::*)()’ [-Wformat]
warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘int (B::*)()’ [-Wformat]
In general, I can only encourage you to turn on warnings.
Now a hack (undefined behavior) is the following:
std::printf("ptr:%p | %p\n",(void*)funcptr,(void*)funcptr);
This still gives the following warning:
warning: converting from ‘int (B::*)()’ to ‘void*’ [-Wpmf-conversions]
but the program prints the same address twice as you wished. It is still undefined behavior, see How to format a function pointer? By following the accepted answer (code shamelessly stolen from there), one could print the address as follows:
#include <cstdio>
class B {
public:
int fun() { return 0; }
};
int main()
{
int (B::*funcptr)()=&B::fun;
unsigned char *p = (unsigned char *)&funcptr;
for (unsigned int i = 0; i < sizeof funcptr; ++i)
{
std::printf("%02x ", p[i]);
}
std::putchar('\n');
return 0;
}
According to that answer it is the only legal way to achieve this. It doesn't give any warning.