This question already has an answer here:
-
Pointers to members representations
2 answers
Let's say we have a class A
class A;
and these typedefs
typedef void (A::*a_func_ptr)(void);
typedef void (*func_ptr)(void);
My question is why sizeof(a_func_ptr) returns 16, while sizeof(func_ptr) returns 4 (as for any pointer on x86 system)?
For instance
int main(int argc, char *argv[])
{
int a = sizeof(a_func_ptr);
int b = sizeof(func_ptr);
}
My question is why sizeof(a_func_ptr) returns 16, while sizeof(func_ptr) returns 4 (as for any pointer on x86 system)?
Because pointer-to-members are implemented differently. They're not pointers under the hood. Some compilers, such as MSVC, implement them as struct
with more than one members in it.
Read this interesting article:
- Pointers to member functions are very strange animals
Note that in some compilers, they might have same size. The bottomline is: they're compiler-dependent.
Pointer-to-member function of class doesn't hold the "exact address" like a regular pointer does. It stores more information than regular function pointer.
So when you use sizeof
to measure the size of a pointer-to-member function of a class, you should not expect that it will be same size as a regular function pointer.
Consider the following:
#include <iostream>
class A {
public:
virtual void foo(){ std::cout << "A::foo" << std::endl; }
void bar(){ std::cout << "A::bar" << std::endl; }
};
class B : public A {
public:
void foo(){ std::cout << "B::foo" << std::endl; }
void bar(){ std::cout << "B::bar" << std::endl; }
};
int main() {
a_func_ptr f = &A::foo;
a_func_ptr g = &A::bar;
B b;
A a;
(b.*f)();
(b.*g)();
(a.*f)();
(a.*g)();
}
Output:
B::foo
A::bar
A::foo
A::bar
Both member pointers are of the same type, yet both correctly routed the call in every cases.
Somehow, the generated programme must know when a pointer to method is actually a simple method or a virtual one. Thus the runtime representation of a method pointer has to include more information to handle the second case.
Remark: the size seems to be implementation dependent (I get 8
on my system).
Pointers to member functions may be a data structure as pointed out in the C++ FAQ here. Also Pointers to member functions are very strange animals offers an example of how it is implemented for Visual C++.
Although function pointers in C and C++ can be implemented as simple
addresses, so that typically sizeof(Fx)==sizeof(void *), member
pointers in C++ are often implemented as "fat pointers", typically two
or three times the size of a simple function pointer, in order to deal
with virtual inheritance.
Source: Wikipedia
This SO answer offers additional information.
A related question is discussed here:
Is the sizeof(some pointer) always equal to four?
See:
Pointers to member functions are very strange animals
for further Information.