Access v-table at run-time
Asked Answered
I

5

6

Is it possible to access a function's v-table at runtime? Can meta-information such as the number of different function versions be determined? This might be more of a theoretical question, but could a developer put a cap on the number of classes that can extend a given base class by making sure the v-table never exceeds a certain number of rows?

Intendancy answered 21/4, 2011 at 5:59 Comment(2)
Somewhat similar question: #5100467Psychotomimetic
Well, you can access the vtable at runtime using assembly (non-portable, obviously)... but you still can't do those other things you asked (determine or limit size of vtable)Writeoff
O
12

Is it possible to access a function's v-table at runtime? Can meta-information such as the number of different function versions be determined?

Not in a portable way. The standard does not even have the concept of virtual table, it is more of an implementation detail than a requirement, even if all implementations I know use vtables. In the general case there will not even be enough information available at runtime (i.e. the compiler does not need to store the number of entries in the vtable, as it sees the type and can count)

Could a developer put a cap on the number of classes that can extend a given base class by making sure the v-table never exceeds a certain number of rows?

Again no, but since this shows a misconception, it might be worth treating it apart. When a base class has any virtual functions the compiler (in all implementations that use vtables) will create the vtable and that table will have exactly 1 entry per virtual function in the base class (plus some additional data --typeinfo or pointer to it, offset to the beginning of the object or other implementation details). When a class extends that base class, it will not add new elements to that vtable, but rather create a separate vtable (or more, depending on the type hierarchy). If the derived function does not add any new virtual function, the vtable for the derived object will contain the exact number of elements that the original vtable had. That is, you can have a huge hierarchy of inheritances without that affecting the vtable layout at all. What will change are the typeinfo data stored and the pointers to each virtual function, that will refer to the final overrider

Ovi answered 21/4, 2011 at 7:26 Comment(2)
+1, especially for addressing the misconception about vtable size and layout.Obstetric
So why bjarne stroustrop book details vtable as part of class structure?Colossian
N
3

an meta-information such as the number of different function versions be determined?

No C++ doesn't support reflection. What you are trying to achieve is not possible in C++ AFAIK

Nicotiana answered 21/4, 2011 at 6:1 Comment(0)
A
1

Theoretically, yes, because it's stored in memory and you have access to it. In practice, there is no sane, portable way to do it, because the compiler is free to implement virtual functions in any way it wants, so you would have to dig through your compiler's source code to find out how/where to access the desired information and how to interpret it.

Almond answered 21/4, 2011 at 6:29 Comment(0)
G
0

You can use the Debug Interface Access SDK or other debug support interfaces (gdb) for this sort of thing.

RTT data is more portable but may not have sufficient details for your project.

For your specific question on limiting the v-table and preventing it from being extended too far, you can try this method;

IDiaSymbol::get_classParente Retrieves a reference to the class parent of the symbol.

HRESULT get_classParent (IDiaSymbol** pRetVal);

You can investigate all of the class related symbol types here, what you might want to do is enumerate all class types loaded, get_classParent recursively and keep a tally of all of the classes which extend your base.

Your class could also require symbols to be available on startup to help with enforcement.

Goodyear answered 21/4, 2011 at 7:18 Comment(3)
A virtual base table pointer is not a pointer to the virtual table of a base, but rather a pointer to the vtable of a virtual base. Note that virtual goes with the base, not the table. As such it only makes sense when you have virtual inheritance: struct derived : virtual base {};Gooden
@David: +1 This answer has got virtual functions and virtual base classes mixed up.Obstetric
I'm sure he'll need to do a lot more than use any one call anyhow, which is why I said "Their's quite a few of other interfaces, you may need to use other methods to get all the information you need." I guess I should of been a bit more emphatic about that need. :\Goodyear
A
0

The only glimmer of hope I could imagine for your effort, is the handling of dynamic_cast. Each compiler, with corresponding library support, has some concept of traversing a hierarchy to achieve a dynamic cast. If you could hook into that traversal, you might then know something about how many levels of inheritance you are dealing with. That said, even if you made this work, it would be compiler-specific (as others have said) since such implementation is proprietary.

Anomalism answered 21/4, 2011 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.