Where are member functions stored for an object?

Johnny Pauling picture Johnny Pauling · Mar 22, 2013 · Viewed 8.1k times · Source

I'm experimenting with C++ to understand how class/structures and their respective objects are laid out in memory and I understood that each field of a class/structure is an offset into their respective object (so I can have a member variable pointer).

I don't understand why, even if I can have member function pointers, the following code doesn't work:

struct mystruct
{
    void function()
    {
        cout << "hello world";
    }
    int c;
};

int main() 
{ 
    unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
    unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function); // ERROR - error C2276: '&' : illegal operation on bound member function expression



    return 0;
}

My question is: why does the line

unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);

compile and returns me the offset of the "c" field from the start of the structure and the line

unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function);

doesn't even compile?

Answer

Luchian Grigore picture Luchian Grigore · Mar 22, 2013

Member functions or pointers to them aren't stored in the object. (virtual functions are typically called through a pointer stored in a table to which an object has a single pointer to) This would be a huge waste of memory. They're typically stored in a code memory section, and are known to the compiler. The object (*this) is typically passed as an invisible parameter so the functions know on which object to operate when they are called.

So, in layman terms, you'd have

 0x10001000    void A::foo
 ..........    {code for A::foo}

and

 push a;
 call A::foo (0x10001000)
 pop a;

where a is the object you're calling foo on.