Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, equivalence between pointer-to-functions and pointer-to-member-functions?

I'm used to thinking of member functions as just being a special case of normal functions, where member functions have an extra parameter at the beginning of their parameter list for the 'this' pointer, that is, the object on which the member function is supposed to act. I've used boost::function this way in the past and never encountered any problems:

boost::function f<(void)(MyObject*, int, int)> = &MyObject::method_that_takes_two_ints;

But I've seen this syntax for member-function pointers:

void (MyObject::*f)( int, int ) = &MyObject::method_that_takes_two_ints;

In this syntax, the 'this' parameter is not visible. Which got me wondering if under the hood pointer-to-member-functions are really a separate beast, and that boost was taking care of details for me.

What does the standard dictate about the placement of the 'this' parameter? Perhaps just on my compiler the extra 'this' argument comes first, and maybe on other compilers it could be on the end? Am I just lucky that my way of thinking is consistent with how my compilers (GCC4, VS2005) handle it? Are pointer-to-member-functions always just a special case of pointer-to-functions with an extra parameter or can the compiler implement them differently?

like image 659
Joseph Garvin Avatar asked Nov 27 '22 06:11

Joseph Garvin


1 Answers

The standard says next to nothing about where the this pointer should be placed, and in fact it is fairly common to use a different calling convention for member functions. (So the 'this' pointer is not just an extra first argument, it's actually stored in a different location than the first arg usually is)

In particular, MSVC uses the thiscall calling convention for member functions, and stdcall elsewhere. http://www.hackcraft.net/cpp/MSCallingConventions/#thiscall describes the differences between them, but note that thiscall stores the this pointer in the ECX register, while stdcall stores all parameters on the stack.

You're definitely better off treating them as completely distinct types. A pointer to a member function is not just a pointer to a function with an extra parameter.

like image 103
jalf Avatar answered Dec 05 '22 11:12

jalf