4

I would like to ask you on what does the offset of the table of virtual functions for a class depend? I mean, from what I've read it at least depends on compiler, but does it varies from class to class?

Edit: by offset I mean the position of the table relative to the address of the owner object.

Edit: example code:

void **vtable = *((void***)(((char*)object)+offset));

int **ivtable=(int **)vtable;

void* firstFunction = (void*) ivtable[0];
MSalters
  • 173,980
  • 10
  • 155
  • 350
user246100
  • 670
  • 1
  • 11
  • 20
  • If it depends on the compiler, well, it fully depends on the compiler—certain may always put the virtual table at the same place in all classes, others may not. – zneak Jan 24 '10 at 03:53
  • Are you just asking because you are curious or do you have a specific problem`to solve? – Georg Fritzsche Jan 24 '10 at 03:54
  • What I want to do is for an area where virtual functions use (hooking and calling) is already done by others. I just want to know if it varies from class to class since what it is already done revolves around the same base class – user246100 Jan 24 '10 at 03:55
  • What is this for? Sorry if I missed it. – GManNickG Jan 24 '10 at 18:47
  • A library for function hooking and calling for half life 1 engine based games – user246100 Jan 24 '10 at 18:49
  • Check the question [V-table thunk](http://stackoverflow.com/questions/1090755/v-table-thunk) – mloskot Jan 24 '10 at 03:58

3 Answers3

5

There is certainly a dependency on the exact class.

Remember that C++ has multiple inheritance (MI). The consequence of MI is that a single object may have multiple base subobjects. Those of course cannot be at the same address. This also means that some base subobjects don't actually start at relative offset 0.

Now, this MI introduces quite a bit of complexity with vtables: you inherit functions from multiple bases, at different offsets. For that reason it's quite common to use different vtable layouts for MI classes.

On a related note, MI also means that not every pointer to an object is actually a pointer to the start of that object. It is quite likely that a SecondBase* pointer to a Derived object is offset by sizeof(FirstBase), i.e. points somewhere in the middle of the Derived object.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Thanks. In my case I don't know of any class that inherits from more than one so I think it's ok to assume a fixed offset. – user246100 Jan 25 '10 at 15:31
3

As it turns out, most/all C++ compilers on the Windows platform use the same virtual function table layout. The designers of Microsoft's COM technology took advanage of this fact so that C++ implementations of COM interfaces can be compiled on all the standard Windows C++ compilers.

I don't have the exact order memorised, but it basically comes down to depth-first left recursion on the object graph, so that the first declared virtual method on the left-most (1st-declared if multiple inheritance is used), deepest derived class is the first virtual method in the table. I don't know if "virtual" inheritance (using the virtual keyword in the declaration of the base class) is standardized, though.

David Gladfelter
  • 4,175
  • 2
  • 25
  • 25
  • From what I've saw in a library that deals with virtual functions hooking, in Windows the offset is always 0. But, in Linux, (that I also need) it varies. What i want to know is if in the same library all the classes have the same offset or not. – user246100 Jan 24 '10 at 04:08
  • ISTR GCC puts the vtable at the _end_ of an object, so not at a fixed offset to the _start_ of an object. – MSalters Jan 26 '10 at 08:49
  • I've already tested and saw that it is located at a fixed offset. – user246100 Jan 26 '10 at 18:53
0

It varies from class to class.

user246100
  • 670
  • 1
  • 11
  • 20