14

I'm trying to make some callbacks from member functions and everything was ok until I tried to use a template class derived from 2 classes as callback object when I got the following error:

error C2440: 'reinterpret_cast' : Pointers to members have different representations; cannot cast between them

This thing signaled me that member function pointers have different representations(doh!)

What are these representations? What is the difference between them?

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211

2 Answers2

23

Danny Kalev explains this quite nicely:

The Underlying Representation of Pointers to Members

Although pointers to members behave like ordinary pointers, behind the scenes their representation is quite different. In fact, a pointer to member usually consists of a struct containing up to four fields in certain cases. This is because pointers to members have to support not only ordinary member functions, but also virtual member functions, member functions of objects that have multiple base classes, and member functions of virtual base classes. Thus, the simplest member function can be represented as a set of two pointers: one holding the physical memory address of the member function, and a second pointer that holds the this pointer. However, in cases like a virtual member function, multiple inheritance and virtual inheritance, the pointer to member must store additional information. Therefore, you can't cast pointers to members to ordinary pointers nor can you safely cast between pointers to members of different types.

To get a notion of how your compiler represents pointers to members, use the sizeof operator. In the following example, the sizes of a pointer to data member and a pointer to a member function are taken. As you can see, they have different sizes, hence, different representations:

struct A
{
 int x;
 void f();
};
int A::*pmi = &A::x;
void (A::*pmf)() = &A::f;
int n = sizeof (pmi); // 8 byte with my compiler
int m = sizeof (pmf); // 12 bytes with my compiler

Note that each of these pointers may have a different representation, depending on the class in question and whether the member function is virtual.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I know this is last year's snow, but the above explanation is incorrect. A pointer-to-member does not contain `this`. The quoted author seemingly confuses pointers-to-members with delegates. Caveat emptor. – n. m. could be an AI Jul 20 '23 at 07:36
5

This is a Microsoft thing: they make pointers to member functions smaller in some cases, at the cost of producing pointers to member functions that have different representations, as you've just seen. There's a switch to turn this off (/vmg), so that all pointers to members have the same representation.

Dr. Gut
  • 2,053
  • 7
  • 26
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • See http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/a9cfa5c4-d90b-4c33-89b1-9366e5fbae74 for a similar discussion and links to the compiler switches. – Martin Schröder Mar 05 '13 at 13:45
  • 1
    See [this online demo](https://godbolt.org/z/RTC_Dt) to see the effects of `/vmb` and `/vmg` compiler switches. – Dr. Gut Oct 02 '19 at 21:11