I tried googling it, but didn't find any result. Is the implementation similar to the class hack in C using struct of function pointers and data? Or is it implemented in some another form?
I have not written any c++ compilers, but the structure of a class should contain:
Note: non-virtual functions are referenced statically, so they should not be bound to a class instance directly.
That said, each compiler probably implements this a bit differently.
TLDR: essentially yes, the implementation has to be similar to the class hack (but this should be transparent/irrelevant for developers).
Edit:
This post is mostly speculation, based on years of debugging with visual studio (very subjective), backed with some experience years ago, maintaining a project that had the class hack supporting inheritance, implemented in C (such experience is very subjective as well).
For an example, in Visual Studio 6, you could see that the virtual function table was allocated before the c++ implementation-specific data. That is, a class looked like this:
[vtbl][data]
^1 ^2
so if this was for (for example) struct X { virtual ~X(); int i; }
, then writing:
X a;
X *p = &a;
would create something similar to this:
[ptr + 1] -> any other virtual functions
[ptr + 0] -> X::~X
^x
[^x][data]
^1 ^2
^p = ^2;
with ^1
being where the operating system would allocate memory (and the vtbl would be filled in within the implementation of new
), then the offset to user data (vtbl + sizeof (vtbl)
) would be returned to the client code, as the address of the class. I don't know if this is still the case.
Yes, normally (or at least sometimes) it would be implemented in a way that you can make it compatible with a "C-hack", but the details differs from compiler to compiler.
This becomes quite natural for a few reasons:
Basically, it's "easy" to implement C++ in a way that the class layout could be described in the accompanying C implementation, but also it's "harder" not to do it.
As a simple case of GCC layout we can consider a class with virtual methods (if it has no virtual method it would be a plain struct layoutwise). The layout will then start with the virtual table pointer which points to an array of words/pointers (containing both function pointers, pointer to the type_info
node, and some other useful information). Then follows the members as if it were a normal struct.
When inheriting it's similar, it starts with the layout of the base class (natural since the pointer to the derived class should be easy to cast to a pointer of the base class) except now the virtual table pointer points to the virtual table of the derived class (which by the way has the same layout as the base class except it may have additional elements corresponding to new virtual methods introduced in the derived class - here to a pointer to the virtual table of the derived class can function as the virtual table of the base class).
In C this would look something like:
struct class_layout {
void **__vptr;
/*
base data members as they appear in the C++ definitions,
(given they have fundamental types)
*/
/*
additional data members introduced in the derived class
*/
};
It would be tempting to define __vptr
as a pointer to a struct
that contains the function pointers, it would work fine except it would not be that compatible with how GCC does it. The detail is that there are entries in the virtual table at negative indices as well (probably for historical reasons).
Then there are some cases that require special care: A base class that doesn't have virtual methods for example would (almost) require that there is no virtual table pointer in the base class. The case of virtual inheritance would require a pointer to the base class object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With