How a vtable's function is found?

Started by
5 comments, last by ChaosEngine 5 years, 8 months ago

I've been going through this tutorial and understood it mostly except the highlighted part. The tutorial explains vpointer and vtables.

Steps are as follows, vpointer hidden in first 4 bytes of the object will be fetched
vTable of this class is accessed through the fetched vPointer
Now from the vTable corresponding function’s address will be fetched
Function will be executed from that function pointer

What I don't understand is the 3rd (bold) part. How does the compiler know which function (function address) to call from its virtual table?

Edit:
I went through this tutorial too which explains it a bit further but the original question still holds. I guess that compiler knows how to get to specific function in vtable by some pointer indexing, like vptr+4 or something. But than how a compiler knows not to overflow and not do a vptr+12 if a +12 does not exist?

Advertisement

The vtable is an array of function addresses.  At compile time, the index into that array is computed based on the type information at the call site (the static type of the variable) and which method is being called.  That index is hardcoded in the instructions that perform the call operation.

A vtable index is same as a function name, it's determined at compile time and won't change and of course won't be over flow. If you debug to see a virtual member function pointer, you will find it's some vtable index instead of pointer to memory.

 

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

The third bold part is known at compile time.  The compiler will make a table of virtual functions to offsets in the vtable so it knows which function pointer in the vtable to look up.

The compiler knows the offset of a function address in the vtable the same way it knows the offset of a local variable address in the stack or the address of a non-virtual function in memory.

If you change the order of virtual functions in a class (for example, adding a new virtual function in the middle) and recompile only part of the program that used that object but not others, you will probably get a crash.  That's called an "ABI mismatch" because the vtable offsets are hard-coded, and it's the bane of C++ developers.  It's a frequent problem using Microsoft Visual Studio, which does a poor job of dependency tracking (and it only has one job, so go figure) and the fix is to force-rebuild the entire project.  It's also a problem with .so files on Linux when developers do not follow best practices (and many believe they know better, so go figure).

Stephen M. Webb
Professional Free Software Developer

Just as an aside, the C++ standard doesn't require a vtable, it simply requires some method of virtual dispatch.

In practice, most, if not all, compilers implement this using a vtable, but in theory, they are free to use whatever method they desire in the background, as long as virtual dispatch still works.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

This topic is closed to new replies.

Advertisement