How is the information about ptr to a virtual member function vs. non virtual function encoded within a function pointer. Clearly this is compiler dependent, but I would like to understand techniques used to encode this information.
#include <cassert>
struct X {
virtual void f() {
}
void f1() {
}
};
struct Y : X {
void f() {
assert(0); // does trigger
}
};
int main() {
auto ptr = &X::f;
X *p = new Y();
(p->*ptr)();
}
A non-virtual class method is, basically, an ordinary function, so a pointer to a non-virtual class method is functionally equivalent to an ordinary function pointer, the function's address.
Every non-static class method, whether virtual or not, receives an internal pointer. You know it as "this". This is, typically, an additional, hidden function parameter.
Every class with virtual inheritance has a hidden internal pointer as one of its class members. It's generated by the compiler and the compiler automatically generates the appropriate code to initialize it when an instance of the class gets created. This pointer points to compiler-generated metadata that, amongst other things, records the pointer to the metadata for the instantiated class and what all the real overridden virtual functions are, for that instance of the class.
A pointer to a virtual class method is an address of a function that digs into this, and uses the this's virtual function dispatch metadata to look up the actual, instantiated class and then use the hidden pointer to virtual class's metadata to look up the appropriate virtual function override, for this object, then (after a few more bookkeeping procedures) jumps to the appropriate, real, virtual function.
So the address of a virtual function is, typically, also an address of a function, except that it's not any specific virtual function, but rather a compiler-generated function that figures out what "real" object it's being invoked for and its appropriate overridden virtual function.
This is the capsule summary of a typical compiler implementation. Some details have been omitted. There are minor variations that differ from compiler to compiler.
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