tags:

views:

232

answers:

2

I am not sure if the question is already addressed. I was checking the one of the Stack overflow function and got this doubt.

Lets check the code first:

#include <string>
#include <map>
#include <iostream.h>

class MyClass
{
public:

    virtual  int Func()
    {
     return 0;
    }

    int Func2()
    {
     return 0;
    }

};

class MyClass2 :  public MyClass
{
public:

    int Func( )
    {
     return 1;
    }

    int Func2()
    {
     return 1;
    }

};

class Processor
{
 private:
      typedef int (MyClass::*MemFuncGetter)();
      static std::map<std::string, MemFuncGetter> descrToFuncMap;

 public:
        static void Initialize();
        void Process(MyClass* m, const std::string&);

};

std::map<std::string, Processor::MemFuncGetter> Processor::descrToFuncMap;
void Processor::Initialize()
{

     descrToFuncMap["Func"]=&MyClass::Func;
     descrToFuncMap["Func2"]=&MyClass::Func2;
};

void Processor::Process(MyClass* ms, const std::string& key)
{
    std::map<std::string, MemFuncGetter>::iterator found = descrToFuncMap.find(key);
     if(found != descrToFuncMap.end())
     {
        MemFuncGetter memFunc = found->second;
        int dResult = (ms->*memFunc)();
     cout << "Result is : "<< dResult <<endl;
      }
 }


int main(int argc, char* argv[])
{
    Processor::Initialize();
    Processor p;

    MyClass *pMC2 = new MyClass2;
    p.Process(pMC2, "Func");
    p.Process(pMC2, "Func2");

    delete pMC2;
    pMC2 = NULL;

    return 0;
}

In this example, the result is as expected:

Result is : 1
Result is : 0

But when I debugged using VC 6 debugger and observed the value of memFunc in Processor::Process and found following values:

In p.Process(pMC2, "Func"); call

memFunc 0x004011bd [thunk]:`vcall'{0,{flat}}'

In p.Process(pMC2, "Func2"); call

memFunc 0x0040118b MyClass::Func2(void)

I didn't understand thunk and flat in "[thunk]:`vcall'{0,{flat}}" ? Can anyone help me to understand the internals here ?

+3  A: 

There is a pretty thorough explanation of what thunk means over on WikiPedia

http://en.wikipedia.org/wiki/Thunk

The gist of is thunk is the mechanism by which the C++ virtual table is accessed at runtime. It is setup to call the appropriate virtual function for the runtime type of the object.

As to what the vcall{0,{flat}} means I am not 100% sure. My guess is that it's reporting the values by which the thunk is accessing the method.

  • 0: Offset in the vtable
  • {flat}: inheritance hierarchy is flat not multiple
JaredPar
A: 

The different notations are because member function pointers need to be able to handle various virtual and non-virtual member functions (although not static member functions) and it needs to be able to handle member functions which belong to the class via various forms of inheritance (public, private and/or virtual).

The best article I've come across that explains how member function pointers work is Doug Clugston's "Member Function Pointers and the Fastest Possible C++ Delegates" on The Code Project.

You'd probably guess that a "member function pointer", like a normal function pointer, just holds a code pointer. You would be wrong. On almost all compilers, a member function pointer is bigger than a function pointer. Most bizarrely, in Visual C++, a member function pointer might be 4, 8, 12, or 16 bytes long, depending on the nature of the class it's associated with, and depending on what compiler settings are used! Member function pointers are more complex than you might expect.

It's not easy reading, but it's worthwhile - the information is difficult to find anywhere else. Giving that article a good read might give you insight into what the debugger is really saying when it shows you things such as

[thunk]:`vcall'{0,{flat}}'

JaredPar's answer is probably pretty much on the mark - Clugstons' article will give you the rest of the story.

Michael Burr