简体   繁体   中英

Addresses of virtual functions in vtable

Lets say there is a class named Person which contains a virtual function named age(). As per language semantics, vtable is per class and not per object. It is VPTR which is per object and points to vtable.

Questions:

If I build this program (lets say main() exist):

  1. Will the vtable be created ie can vtable comes in existence w/o even creating a single object?

  2. The address which is put by compiler in vtable for age() is a kind of some static address in memory?

  3. Or is it that compiler internally creates some object for obtaining the address to age() (since age() will be working on some data members which can come in existence only when an object is constructed) or there is some other magic behind this?

As per my understanding, the answers are as follows:

  1. Yes
  2. Yes
  3. Not sure

I tried running "nm" on above program just to see if I can figure out the vtable, but no luck. Is there a way to do so?

Please suggest.

Since it's all implementation defined, my answer describes some 'common implementation'

  1. The v-table is stored in the executable just like the machine-code itself, and loaded to the memory by the OS loader. The OS dosn't care what data to load: string literals, machine code, vtables, constant data, etc...

  2. Suppose you have:

     struct A { int x; virtual void f() { cout << x; } }; void g(A* a) { a->f(); } 

    The generated code will look (semantically) similar to:

     // pseudocode, not C++ struct A { void *vtable; int x; }; void A_f(A* this) { cout << this->x; } void* A_vtable[] = { &A_f }; void g(A* a) { ((void(*)(A*))(((void**)a->vtable)[0]))(a); } 

    So yes, it's static data.

    Of course the above code is very simplified. To support RTTI and virtual inheritance you must do more complicated things.

  3. I don't understand what you mean, but No.

The answers to all of these are completely compiler-dependent. There is no requirement that a physical vtbl even exists; that's just a very common way of implementing the language. But there's no universal ABI for any of this, and it's not something that you as a developer should be worrying about.

This is all compiler dependent, and you should take the whole answer just as a way in which it can be done:

Will the vtable be created ie can vtable comes in existence w/o even creating a single object?

Depends on the compiler and the program. For example, GCC will create the vtable in the translation unit in which the first virtual function that is not defined inside the class definition is defined (whether any object is created or not), but it might not generate a vtable at all in some cases or it might generate one even if no objects are created.

The address which is put by compiler in vtable for age() is a kind of some static address in memory?

That is usually resolved by the linker/loader. When the program is linked, the linker usually resolves the (relative) addresses of the functions and injects those into the vtable as a first step. When the program is loaded into memory those addresses are fixed to the memory addresses in which the functions are (which depending on the loader can vary from one execution to another).

Or is it that compiler internally creates some object for obtaining the address to age() (since age() will be working on some data members which can come in existence only when an object is constructed) or there is some other magic behind this?

I don't quite follow the whole question. The compiler does not create any object of the type that has the member age artificially, only if your program requests it. The members functions potentially access/modify data members of an object of a given type, but access to those members is handled by means of the implicit this pointer that pass to all non-static members.

"As per language semantics," there's no such thing as a vtable. The C++ specification does not specify exactly how virtual dispatch is implemented. A compiler could use vtables. Or it could use something else; that's up to the compiler.

A specific compiler can use vtables of course. But it can do whatever it wants with them; that's an implementation detail. In short, there's no way for you to know without investigating the specific compiler you're using.

And really, does it matter that much?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM