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):
Will the vtable be created i.e can vtable comes in existence w/o even creating a single object?
The address which is put by compiler in vtable for age() is a kind of some static address in memory?
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:
Yes
Yes
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'
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...
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.
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 i.e 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?
Related
Can someone explains how this virtual table for the different class is stored in memory? When we call a function using pointer how do they make a call to function using address location? Can we get these virtual table memory allocation size using a class pointer? I want to see how many memory blocks is used by a virtual table for a class. How can I see it?
class Base
{
public:
FunctionPointer *__vptr;
virtual void function1() {};
virtual void function2() {};
};
class D1: public Base
{
public:
virtual void function1() {};
};
class D2: public Base
{
public:
virtual void function2() {};
};
int main()
{
D1 d1;
Base *dPtr = &d1;
dPtr->function1();
}
Thanks! in advance
The first point to keep in mind is a disclaimer: none of this is actually guaranteed by the standard. The standard says what the code needs to look like and how it should work, but doesn't actually specify exactly how the compiler needs to make that happen.
That said, essentially all C++ compilers work quite similarly in this respect.
So, let's start with non-virtual functions. They come in two classes: static and non-static.
The simpler of the two are static member functions. A static member function is almost like a global function that's a friend of the class, except that it also needs the class`s name as a prefix to the function name.
Non-static member functions are a little more complex. They're still normal functions that are called directly--but they're passed a hidden pointer to the instance of the object on which they were called. Inside the function, you can use the keyword this to refer to that instance data. So, when you call something like a.func(b);, the code that's generated is pretty similar to code you'd get for func(a, b);
Now let's consider virtual functions. Here's where we get into vtables and vtable pointers. We have enough indirection going on that it's probably best to draw some diagrams to see how it's all laid out. Here's pretty much the simplest case: one instance of one class with two virtual functions:
So, the object contains its data and a pointer to the vtable. The vtable contains a pointer to each virtual function defined by that class. It may not be immediately apparent, however, why we need so much indirection. To understand that, let's look at the next (ever so slightly) more complex case: two instances of that class:
Note how each instance of the class has its own data, but they both share the same vtable and the same code--and if we had more instances, they'd still all share the one vtable among all the instances of the same class.
Now, let's consider derivation/inheritance. As an example, let's rename our existing class to "Base", and add a derived class. Since I'm feeling imaginative, I'll name it "Derived". As above, the base class defines two virtual functions. The derived class overrides one (but not the other) of those:
Of course, we can combine the two, having multiple instances of each of the base and/or derived class:
Now let's delve into that in a little more detail. The interesting thing about derivation is that we can pass a pointer/reference to an object of the derived class to a function written to receive a pointer/reference to the base class, and it still works--but if you invoke a virtual function, you get the version for the actual class, not the base class. So, how does that work? How can we treat an instance of the derived class as if it were an instance of the base class, and still have it work? To do it, each derived object has a "base class subobject". For example, lets consider code like this:
struct simple_base {
int a;
};
struct simple_derived : public simple_base {
int b;
};
In this case, when you create an instance of simple_derived, you get an object containing two ints: a and b. The a (base class part) is at the beginning of the object in memory, and the b (derived class part) follows that. So, if you pass the address of the object to a function expecting an instance of the base class, it uses on the part(s) that exist in the base class, which the compiler places at the same offsets in the object as they'd be in an object of the base class, so the function can manipulate them without even knowing that it's dealing with an object of the derived class. Likewise, if you invoke a virtual function all it needs to know is the location of the vtable pointer. As far as it cares, something like Base::func1 basically just means it follows the vtable pointer, then uses a pointer to a function at some specified offset from there (e.g., the fourth function pointer).
At least for now, I'm going to ignore multiple inheritance. It adds quite a bit of complexity to the picture (especially when virtual inheritance gets involved) and you haven't mentioned it at all, so I doubt you really care.
As to accessing any of this, or using in any way other than simply calling virtual functions: you may be able to come up with something for a specific compiler--but don't expect it to be portable at all. Although things like debuggers often need to look at such stuff, the code involved tends to be quite fragile and compiler-specific.
The virtual table is supposed to be shared between instances of a class. More precisely, it lives at the "class" level, rather than the instance level. Each instance has the overhead of actually having a pointer to the virtual table, if in it's hierarchy there are virtual functions and classes.
The table itself is at least the size necessary to hold a pointer for each virtual function. Other than that, it is an implementation detail how it's actually defined. Check here for a SO question with more details about this.
First of all, the following answer contain almost everything you want to know regarding virtual tables:
https://stackoverflow.com/a/16097013/8908931
If you are looking for something a little more specific (with the regular disclaimer that this might change between platforms, compilers, and CPU architectures):
When needed, a virtual table is being created for a class. The class will have only one instance of the virtual table, and each object of the class will have a pointer which will point to the memory location of this virtual table. The virtual table itself can be thought of as a simple array of pointers.
When you assigned the derived pointer to the base pointer, it also contain the pointer to the virtual table. This mean that the base pointer points to the virtual table of the derived class. The compiler will direct this call to an offset into the virtual table, which will contain the actual address of the function from the derived class.
Not really. Usually at the start of an object, there is a pointer to the virtual table itself. But this will not help you too much, as it is just an array of pointers, with no real indication of its size.
Making a very long answer short: For an exact size you can find this information in the executable (or in segments loaded from it to the memory). With enough knowledge of how the virtual table works, you can get a pretty accurate estimation, given you know the code, the compiler, and the target architecture.
For the exact size, you can find this information in either the executable, or in segments in the memory which are being loaded from the executable. An executable is usually an ELF file, this kind of files, contain information which is needed to run a program. A part of this information is symbols for various kinds of language constructs such as variables, functions and virtual tables. For each symbol, it contains the size it takes in memory. So button line, you will need the symbol name of the virtual table, and enough knowledge in ELF in order to extract what you want.
The answer that Jerry Coffin gave is excellent in explaining how virtual function pointers work to achieve runtime polymorphism in C++. However, I believe that it is lacking in answering where in memory the vtable is stored. As others have pointed out this is not dictated by the standard.
However, there is an excellent blog post(s) by Martin Kysel that goes into great detail about where virtual tables are stored. To summarize the blog post(s):
One vtable is created for every class (not instance) with virtual functions. Each instance of this class points to the same vtable in memory
Each vtable is stored in read only memory of the resulting binary file
The disassembly for each function in the vtable is stored in the text section of the resulting ELF binary
Attempting to write over the vtable, located in read only memory, results in a Segmentation fault (as expected)
Each class has a pointer to a list of functions, they are each in the same order for derived classes, then the specific functions that are overrided change at that position in the list.
When you point with a base pointer type, the pointed to object still has the correct _vptr.
Base's
Base::function1()
Base::function2()
D1's
D1::function1()
Base::function2()
D2's
Base::function1()
D2::function2()
Further derived drom D1 or D2 will just add their new virtual functions in the list below the 2 current.
When calling a virtual function we just call the corresponding index, function1 will be index 0
So your call
dPtr->function1();
is actually
dPtr->_vptr[0]();
So I have read this about if class definitions occupy memory and this about if function occupy memory. This is what I do not get: How come class definitions do not occupy memory if functions do, or their code does. I mean, class definitions are also code, so shouldn't that occupy memory just like function code does?
It is not entirely correct to say that class definitions do not occupy memory: any class with member functions may place some code in memory, although the amount of code and its actual placement depends heavily on function inlining.
The Q&A at the first link talks about sizeof, which shows a per-instance memory requirement of the class, which excludes memory requirements for storing member functions, static members, inlined functions, dispatch tables, and so on. This is because all these elements are shared among all instances of the class.
You don't need to keep the class definition anywhere, because the details of how to create an instance of a class are encoded in its constructors.
(In a sense, the class definition is code, it's just not represented explicitly.)
All you need to know in order to create an object is
How big it is,
Which constructor to use for creating it, and
Which its virtual functions are.
To create an instance of class A:
Reserve a piece of memory of size sizeof(A) (or be handed one),
Associate that piece of memory with the virtual functions of A, if any (usually held in a table in a predetermined location), and
Tell the relevant A constructor where the A should be created, and then let it do the actual work.
You don't need to know a thing about the types of member variables or anything like that, the constructors know what to do once they know where the object is to be created.
(Every member variable can be found at an offset from the beginning of the object, so the constructor knows where things must be.)
To create a function, on the other hand, you would need to store its definition in some form and then generate the code at runtime. (This is usually called "Just-in-time" compilation.)
This requires a compiler, which means that you need to either
Include a compiler in every executable, or
Provide (or require everyone to install) a shared compiler for all executables (Java VMs usually contain at least one).
C++ compilers instead generate the functions in advance.
Abusing terminology a little, you could say that the functions are "instantiated" by the compilation process, with the source code as a blueprint.
Recently, I've come across a couple of type-erasure implementations that use a "hand-rolled" vtable - Adobe ASL's any_regular_t is one example, although I've seen it used in Boost ASIO, too (for the completion routine queue).
Basically, the parent type is passed a pointer to a static type full of function pointers defined in the child type, similar to the below...
struct parent_t;
struct vtbl {
void (*invoke)(parent_t *, std::ostream &);
};
struct parent_t {
vtbl *vt;
parent_t(vtbl *v) : vt(v) { }
void invoke(std::ostream &os) {
vt->invoke(this, os);
}
};
template<typename T>
struct child_t : parent_t {
child_t(T val) : parent_t(&vt_), value_(val) { }
void invoke(std::ostream &os) {
// Actual implementation here
...
}
private:
static void invoke_impl(parent_t *p, std::ostream &os) {
static_cast<child_t *>(p)->invoke(os);
}
T value_;
static vtbl vt_;
};
template<typename T>
vtbl child_t<T>::vt_ = { &child_t::invoke_impl };
My question is, what is the advantage of this idiom? From what I can tell, it's just a re-implementation of what a compiler would provide for free. Won't there still be the overhead of an extra indirection when parent_t::invoke calls vtbl::invoke.
I'm guessing that it's probably got something to do with the compiler being able to inline, or optimize out the call to vtbl::invoke or something, but I'm not comfortable enough with Assembler to be able to work this out myself.
A class having a useful vtable basically requires that it be dynamically allocated. While you can do a fixed storage buffer and allocate there, it is a hassle; you don't have reasonable control over the size of instances once you go virtual. With a manual vtable, you do.
Glancing at the source in question, there are a lot of asserts about the size of various structures (because they need to fit in an array of two doubles in one case).
Also a "class" with a hand-rolled vtable can be standard layout; certain kinds of casting becomes legal if you do this. I don't see this being used in the Adobe code.
In some cases, it can be allocated separately from the vtable entirely (as I do when I do view-based type erasure: I create a custom vtable for the incoming type, and store a void* for it, then dispatch my interface to said custom vtable). I don't see this being used in the Adobe code; but an any_regular_view that acts as a pseudo-reference to an any_regular might use this technique. I use it for things like can_construct<T>, or sink<T>, or function_view<Sig> or even move_only_function<Sig> (ownership is handled by a unique_ptr, operations via a local vtable with 1 entry).
You can create dynamic classes if you have a hand-rolled vtable, where you allocate a vtable entry and set its pointers to whatever you choose (possibly programmatically). If you have 10 methods, each of which can be in one of 10 states, that would require 10^10 different classes with normal vtables. With a hand-rolled vtable, you just need to manage each classes' lifetime in a table somewhere (so instances don't outlive the class).
As an example, I could take a method, and add a "run before" or "run after" method to it, on a particular instance of a class (with careful lifetime management), or on every instance of that class.
It is also possible that the resulting vtables might be simpler than compiler-generated ones in various ways, as they aren't as powerful. Compiler-generated vtables handle virtual inheritance and dynamic casting, for example. The virtual inheritance case might have no overhead unless used, but dynamic casting may require overhead.
You can also gain control over initialization. With a compiler-generated vtable, the status of the table is defined (or left undefined) as the standard dictates: with a hand-rolled one, you can ensure any invariants you choose hold.
The OO pattern existed in C before C++ came around. C++ simply chose a few reasonable options; when you go back to pseudo-C style manual OO, you get access to those alternative options. You can dress things up (with glue) so that they look like normal C++ types to the casual user, while inside they are anything but.
I tried to find where exactly virtual function table gets stored for c++ class.
i found some answers like its a "static array of function pointers"
so will it get stored in data segment read only memory? (initialised one)
Most probably yes. However, it's not mandated. It's not even mandated that polymorphism is implemented via virtual function table, but on most platforms it is. These are implementation details, as long as a compiler obeys the behavior set by the standard, it can do whatever it wants.
A vftable is one per class and stored in only one place in memory.
When you make any function virtual, the compiler will insert a vptr inside your class. As a result, the size of the class will grow by 4 bytes (on Win32).This pointer holds the address of the virtual table (vtable). vtable is constructed by the compiler at compile time and is basically nothing but an array of function pointers. The function pointers are actually pointers to the virtual functions of that particular class. To be more exact, the virtual table is a static array of function pointers, so that different instances of the same class can share that vtable. Since, static members are stored in the data section (.data), the vtable is also stored in the data section of the executable.
It's implementation dependent, yes.
And for g++ (4.9.0), virtual table (not the pointer) is stored in the section .rodata of ELF file and its corresponding segment LOAD in memory.
I'm trying to understand what kind of memory hit I'll incur by creating a large array of objects. I know that each object - when created - will be given space in the HEAP for member variables, and I think that all the code for every function that belongs to that type of object exists in the code segment in memory - permanently.
Is that right?
So if I create 100 objects in C++, I can estimate that I will need space for all the member variables that object owns multiplied by 100 (possible alignment issues here), and then I need space in the code segment for a single copy of the code for each member function for that type of object( not 100 copies of the code ).
Do virtual functions, polymorphism, inheritance factor into this somehow?
What about objects from dynamically linked libraries? I assume dlls get their own stack, heap, code and data segments.
Simple example (may not be syntactically correct):
// parent class
class Bar
{
public:
Bar() {};
~Bar() {};
// pure virtual function
virtual void doSomething() = 0;
protected:
// a protected variable
int mProtectedVar;
}
// our object class that we'll create multiple instances of
class Foo : public Bar
{
public:
Foo() {};
~Foo() {};
// implement pure virtual function
void doSomething() { mPrivate = 0; }
// a couple public functions
int getPrivateVar() { return mPrivate; }
void setPrivateVar(int v) { mPrivate = v; }
// a couple public variables
int mPublicVar;
char mPublicVar2;
private:
// a couple private variables
int mPrivate;
char mPrivateVar2;
}
About how much memory should 100 dynamically allocated objects of type Foo take including room for the code and all variables?
It's not necessarily true that "each object - when created - will be given space in the HEAP for member variables". Each object you create will take some nonzero space somewhere for its member variables, but where is up to how you allocate the object itself. If the object has automatic (stack) allocation, so too will its data members. If the object is allocated on the free store (heap), so too will be its data members. After all, what is the allocation of an object other than that of its data members?
If a stack-allocated object contains a pointer or other type which is then used to allocate on the heap, that allocation will occur on the heap regardless of where the object itself was created.
For objects with virtual functions, each will have a vtable pointer allocated as if it were an explicitly-declared data member within the class.
As for member functions, the code for those is likely no different from free-function code in terms of where it goes in the executable image. After all, a member function is basically a free function with an implicit "this" pointer as its first argument.
Inheritance doesn't change much of anything.
I'm not sure what you mean about DLLs getting their own stack. A DLL is not a program, and should have no need for a stack (or heap), as objects it allocates are always allocated in the context of a program which has its own stack and heap. That there would be code (text) and data segments in a DLL does make sense, though I am not expert in the implementation of such things on Windows (which I assume you're using given your terminology).
Code exists in the text segment, and how much code is generated based on classes is reasonably complex. A boring class with no virtual inheritance ostensibly has some code for each member function (including those that are implicitly created when omitted, such as copy constructors) just once in the text segment. The size of any class instance is, as you've stated, generally the sum size of the member variables.
Then, it gets somewhat complex. A few of the issues are...
The compiler can, if it wants or is instructed, inline code. So even though it might be a simple function, if it's used in many places and chosen for inlining, a lot of code can be generated (spread all over the program code).
Virtual inheritance increases the size of polymorphic each member. The VTABLE (virtual table) hides along with each instance of a class using a virtual method, containing information for runtime dispatch. This table can grow quite large, if you have many virtual functions, or multiple (virtual) inheritance. Clarification: The VTABLE is per class, but pointers to the VTABLE are stored in each instance (depending on the ancestral type structure of the object).
Templates can cause code bloat. Every use of a templated class with a new set of template parameters can generate brand new code for each member. Modern compilers try and collapse this as much as possible, but it's hard.
Structure alignment/padding can cause simple class instances to be larger than you expect, as the compiler pads the structure for the target architecture.
When programming, use the sizeof operator to determine object size - never hard code. Use the rough metric of "Sum of member variable size + some VTABLE (if it exists)" when estimating how expensive large groups of instances will be, and don't worry overly about the size of the code. Optimise later, and if any of the non-obvious issues come back to mean something, I'll be rather surprised.
Although some aspects of this are compiler vendor dependent, all compiled code goes into a section of memory on most systems called text segment. This is separate from both the heap and stack sections (a fourth section, data, holds most constants). Instantiating many instances of a class incurs run-time space only for its instance variables, not for any of its functions. If you make use of virtual methods, you will get an additional, but small, bit of memory set aside for the virtual look-up table (or equivalent for compilers that use some other concept), but its size is determined by the number of virtual methods times the number of virtual classes, and is independent of the number of instances at run-time.
This is true of statically and dynamically linked code. The actual code all lives in a text region. Most operating systems actually can share dll code across multiple applications, so if multiple applications are using the same dll's, only one copy resides in memory and both applications can use it. Obviously there is no additional savings from shared memory if only one application uses the linked code.
You can't completely accurately say how much memory a class or X objects will take up in RAM.
However to answer your questions, you are correct that code exists only in one place, it is never "allocated". The code is therefore per-class, and exists whether you create objects or not. The size of the code is determined by your compiler, and even then compilers can often be told to optimize code size, leading to differing results.
Virtual functions are no different, save the (small) added overhead of a virtual method table, which is usually per-class.
Regarding DLLs and other libraries... the rules are no different depending on where the code has come from, so this is not a factor in memory usage.
The information given above is of great help and gave me some insight in C++ memory structure. But I would like to add here is that no matter how many virtual functions in a class, there will always be only 1 VPTR and 1 VTABLE per class. After all the VPTR points to the VTABLE, so there is no need for more than one VPTR in case of multiple virtual functions.
Your estimate is accurate in the base case you've presented. Each object also has a vtable with pointers for each virtual function, so expect an extra pointer's worth of memory for each virtual function.
Member variables (and virtual functions) from any base classes are also part of the class, so include them.
Just as in c you can use the sizeof(classname/datatype) operator to get the size in bytes of a class.
Yes, that's right, code isn't duplicated when an object instance is created. As far as virtual functions go, the proper function call is determined using the vtable, but that doesn't affect object creation per se.
DLLs (shared/dynamic libraries in general) are memory-mapped into the process' memory space. Every modification is carried on as Copy-On-Write (COW): a single DLL is loaded only once into memory and for every write into a mutable space a copy of that space is created (generally page-sized).
if compiled as 32 bit. then sizeof(Bar) should yield 4.
Foo should add 10 bytes (2 ints + 2 chars).
Since Foo is inherited from Bar. That is at least 4 + 10 bytes = 14 bytes.
GCC has attributes for packing the structs so there is no padding. In this case 100 entries would take up 1400 bytes + a tiny overhead for aligning the allocation + some overhead of for memory management.
If no packed attribute is specified it depends on the compilers alignment.
But this doesn't consider how much memory vtable takes up and size of the compiled code.
It's very difficult to give an exact answer to yoour question, as this is implementtaion dependant, but approximate values for a 32-bit implementation might be:
int Bar::mProtectedVar; // 4 bytes
int Foo::mPublicVar; // 4 bytes
char Foo::mPublicVar2; // 1 byte
There are allgnment issues here and the final total may well be 12 bytes. You will also have a vptr - say anoter 4 bytes. So the total size for the data is around 16 bytes per instance. It's impossible to say how much space the code will take up, but you are correct in thinking there is only one copy of the code shared between all instances.
When you ask
I assume dlls get their own stack,
heap, code and data segments.
Th answer is that there really isn't much difference between data in a DLL and data in an app - basically they share everything between them, This has to be so when you think about about it - if they had different stacks (for example) how could function calls work?