2

in How to print member function address in C++ it use (void *&) to type cast the variable, I have tried to use the (void *), but there is something wrong with it. what I am asking is what's the difference between (void *)variable and (void *&) variable in C++ when type casting. the code snippet in the link:

void TestClass::PrintMyFuncAddress(void)
{
  void (TestClass::* ptrtofn)() = &TestClass::MyFunc;
  cout << (void*&)ptrtofn<< endl;
}
Community
  • 1
  • 1
toolchainX
  • 1,998
  • 3
  • 27
  • 43
  • Do you know what the difference between `void *` and `void *&` is in general, and you're just confused about casting? – Useless Nov 02 '12 at 17:15
  • @Useless `void * b; void * &a = b` `a` is a reference (or alias) to b whose type is (void *), am I right? – toolchainX Nov 02 '12 at 17:32

2 Answers2

2

The void* cast tries to convert the value of ptrtofun, to a value of type pointer-to-void. C++ provides no such conversion from pointer-to-member-function to void*, which is why there's something wrong with it (probably it doesn't compile).

The void*& cast creates a reference, whose referand is the first sizeof(void*) bytes of memory starting at the first byte occupied by the object ptrtofn. ptrtofun doesn't have type void* or a compatible type, and need not even be the same size as void*. So using the reference has undefined behavior (it's a violation of strict aliasing) but the compiler need not catch the problem.

Just about the only way to portably print a pointer-to-member function is to print sizeof(ptrtofun) bytes starting from (unsigned char*)(&ptrtofun). You can decide for yourself exactly how you want to represent those bytes (hex being the obvious choice), but be aware that the result is not necessarily the address in memory of the code for TestClass::MyFunc. Pointers-to-member-function simply don't work like that, because for example they need to allow for a pointer to a virtual function, which will call different code according to the dynamic type of the object that it's called on.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
0

Cast to void *& will give you reference to void * type which means it can be used as l-value. void * will give r-value which can be used in expression. But this actually is not relevant to your question.

You cannot convert pointer to member function to pointer to data or to pointer to function; these are fundamentally different types. Usually sizeof(ptr_to_member_function) != sizeof(void*) (or sizeof(void (*)() for that matter).

Pointer to member function does not necessarily contain pointer to the beginning of the code for that function. It may contain offset to VTBL for virtual functions.

While I am not sure I am pretty confident C++ standard does not allow these conversions.

Tomek
  • 4,554
  • 1
  • 19
  • 19