c++: Does a vtable contains pointers to non-virtual functions? - c++

vtable contains pointers to virtual functions of that class. Does it also contains pointers to non-virtual functions as well?
Thx!

It's an implementation detail, but no. If an implementation put pointers to non-virtual functions into a vtable it couldn't use these pointers for making function calls because it would often cause incorrect non-virtual functions to be called.
When a non-virtual function is called the implementation must use the static type of the object on which the function is being called to determine the correct function to call. A function stored in a vtable accessed by a vptr will be dependent on the dynamic type of the object, not any static type of a reference or pointer through which it is being accessed.

No, it doesn't.
As calls to non-virtual methods can be resolved during compilation (since compiler knows the addresses of non virtual functions), the compiler generates instructions to call them 'directly' (i.e. statically).
There is no reason to go through vtable indirection mechanism for methods which are known during compiling.

Whether or not a "vtable" is used by any implementation isn't defined by the standard. Most implementations use a table of function pointers although the functions pointed to are typically not directly those being called (instead, the pointed to function may adjust the pointer before calling the actual function).
Whether or not non-virtual functions show up in this table is also not defined by standard. After all, the standard doesn't even require the existence of a vtable. Normally, non-virtual function are not in a virtual function table since any necessary pointer adjustments and call can be resolved at compile- or link-time. I could imagine an implementation treating all functions similarly and, thus, using a pointer in the virtual function table in all cases. I wouldn't necessary be very popular. However, it might be a good way to implement C++ in an environment where it seamlessly interacts with a more flexible object system, e.g., languages where individual functions can be replaced at run-time (my understanding is that something like this is possible, e.g., in python).

No. A vtable only contains pointers to virtual functions in the same class or file.

Related

Does each object in c++ contain a different version of the class's member functions?

I was just curious, does the creation of an object in C++ allocate space for a new copy of it's member functions? At the assembly or machine code level, where no classes exist, do all calls for a specific function from different objects of the same class actually refer to the same function pointer or are there multiple function blocks in memory and therefore different pointers for each and every member function of every object derived from the same class?
Usually languages implement functionalities as simply as possible.
Class methods are under the hood just simple functions containing object pointer as an argument, where object in fact is just data structure + functions that can operate on this data structure.
Normally compiler knows which function should operate on the object.
However if there is a case of polymorphism where function may be overriden.
Then compiler doesn't know what is the type of class, it may be Derived1 or Derived2.
Then compiler will add a VTable to this object that will contain function pointers to functions that could have been overridden.
Then for overridable methods the program will make a lookup in this table to see which function should be executed.
You can see how it can be implemented by seeing how polymorphism can be implemented in C:
How can I simulate OO-style polymorphism in C?
No, it does not. Functions are class-wide. When you allocate an object in C++ it will contain space for all its attributes plus a VTable with pointers to all its methods/functions, be it from its own class or inherited from parent classes.
When you call a method on that object, you essentially perform a look-up on that VTable and the appropriate method is called.

When virtual functions are invoked statically?

What is the performance difference between calling a virtual function from a derived class pointer directly vs from a base class pointer to the same derived class?
In the derived pointer case, will the call be statically bound, or dynamically bound? I think it'll be dynamically bound because there's no guarantee the derived pointer isn't actually pointing to a further derived class. Would the situation change if I have the derived class directly by value (not through pointer or reference)? So the 3 cases:
base pointer to derived
derived pointer to derived
derived by value
I'm concerned about performance because the code will be run on a microcontroller.
Demonstrating code
struct Base {
// virtual destructor left out for brevity
virtual void method() = 0;
};
struct Derived : public Base {
// implementation here
void method() {
}
}
// ... in source file
// call virtual method from base class pointer, guaranteed vtable lookup
Base* base = new Derived;
base->method();
// call virtual method from derived class pointer, any difference?
Derived* derived = new Derived;
derived->method();
// call virtual method from derived class value
Derived derivedValue;
derived.method();
In theory, the only C++ syntax that makes a difference is a member function call that uses qualified member name. In terms of your class definitions that would be
derived->Derived::method();
This call ignores the dynamic type of the object and goes directly to Derived::method(), i.e. it's bound statically. This is only possible for calling methods declared in the class itself or in one of its ancestor classes.
Everything else is a regular virtual function call, which is resolved in accordance with the dynamic type of the object used in the call, i.e. it is bound dynamically.
In practice, compilers will strive to optimize the code and replace dynamically-bound calls with statically-bound calls in contexts where the dynamic type of the object is known at compile time. For example
Derived derivedValue;
derivedValue.method();
will typically produce a statically-bound call in virtually every modern compiler, even though the language specification does not provide any special treatment for this situation.
Also, virtual method calls made directly from constructors and destructors are typically compiled into statically-bound calls.
Of course, a smart compiler might be able to bind the call statically in a much greater variety of contexts. For example, both
Base* base = new Derived;
base->method();
and
Derived* derived = new Derived;
derived->method();
can be seen by the compiler as trivial situations that easily allow for statically-bound calls.
Virtual functions must be compiled to work as if they were always called virtually. If your compiler compiles a virtual call as a static call, that's an optimization that must satisfy this as-if rule.
From this, it follows that the compiler must be able to prove the exact type of the object in question. And there are some valid ways in which it can do this:
If the compiler sees the creation of the object (the new expression or the automatic variable from which the address is taken) and can prove that that creation is actually the source of the current pointer value, that gives it the precise dynamic type it needs. All your examples fall into this category.
While a constructor runs, the type of the object is exactly the class containing the running constructor. So any virtual function call made in a constructor can be resolved statically.
Likewise, while a destructor runs, the type of the object is exactly the class containing the running destructor. Again, any virtual function call can be resolved statically.
Afaik, these are all the cases that allow the compiler to convert a dynamic dispatch into a static call.
All of these are optimizations, though, the compiler may decide to perform the runtime vtable lookup anyway. But good optimizing compilers should be able to detect all three cases.
There should be no difference between the first two cases, since the very idea of virtual functions is to call always the actual implementation. Leaving compiler optimisations aside (which in theory could optimise all virtual function calls away if you construct the object in the same compilation unit and there is no way the pointer can be altered in between), the second call must be implemented as a indirect (virtual) call as well, since there could be a third class inheriting from Derived and implementing that function as well. I would assume that the third call will not be virtual, since the compiler knows the actual type already at compile time. Actually you could make sure of this by not defining the function as virtual, if you know you will always do the call on the derived class directly.
For really lightweight code running on a small microcontroller I would recommend avoiding defining functions as virtual at all. Usually there is no runtime abstraction required. If you write a library and need some kind of abstraction, you can maybe work with templates instead (which give you some compile-time abstraction).
At least on PC CPUs I often find virtual calls one of the most expensive indirections you can have (probably because branch prediction is more difficult). Sometimes one can also transform the indirection to the data level, e.g. you keep one generic function which operates on different data which is indirected with pointers to the actual implementation. Of course this will work only in some very specific cases.
At run-time.
BUT: Performance as compared to what? It isn't valid to compare a virtual function call to a non-virtual function call. You need to compare it to a non-virtual function call plus an if, a switch, an indirection, or some other means of providing the same function. If the function doesn't embody a choice among implementations, i.e. doesn't need to be virtual, don't make it virtual.

-> operator on null objects

According to C++ Standard, it's perfectly acceptable to do this:
class P
{
void Method() {}
};
...
P* p = NULL;
p->Method();
However, a slight change to this:
class P
{
virtual void Method() {}
};
...
P* p = NULL;
p->Method();
produces an access violation when compiled with Visual Studio 2005.
As far as I understand, this is caused by some quirk in Microsoft's compiler implementation and not by my sheer incompetence for a change, so the questions are:
1) Does this behavior persist in more recent versions of VS?
2) Are there any, I don't know, compiler settings that prevent this access violation?
According to C++ Standard, it's perfectly acceptable to do this
No it is not!
Dereferencing a NULL pointer is Undefined Behavior as per the C++ Standard.[#1]
However, If you do not access any members inside a non virtual member function it will most likely work on every implementation because for a non virtual member function the this only needs to be derefernced for accessing members of this since there are no members being accessed inside the function hence the result.
However, just because the observable behavior is okay does not mean the program is well-formed. correct.
It still is ill-formed.
It is an invalid program nevertheless.
The second version crashes because while accessing a virtual member function, the this pointer needs to be dereferenced just even for calling the appropriate member function even if there are no members accessed within that member function.
A good read:
What's the difference between how virtual and non-virtual member functions are called?
[#1]Reference:
C++03 Standard: ยง1.9/4
Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior. ]
As said by AIs... I'll even explain why: in many C++ implementations the this pointer is simply passed as the first "hidden" parameter of the method. So what you see as
void Method() {}
is really
void Method(P* this) {}
But for virtual methods it's more complex. The runtime needs to access the pointer to find the "real" type of P* to be able to call the "right" virtual implementation of the method. So it's something like
p->virtualTable->Method(p);
so p is always used.
First of all, neither one will even compile, because you've defined Method as private.
Assuming you make Method public, you end up with undefined behavior in both cases. Based on the typical implementation, most compilers will allow the first to "work" (for a rather loose definition of work) while the second will essentially always fail.
This is because a non-virtual member function is basically a normal function that receives an extra parameter. Inside that function, the keyword this refers to that extra parameter, which is a pointer to the class instance for which the function was invoked. If you invoke the member function via a null pointer, it mostly means that inside that function this will be a null pointer. As long as nothing in the function attempts to dereference this, chances are pretty good that you see any noticeable side effects.
A virtual function, however, is basically a function called via a pointer. In a typical implementation, any class that has one or more virtual functions (whether defined directly in that class, or inherited from a base class) will have a vtable. Each instance of that class (i.e., each object) will contain a pointer to the vtable for its class. When you try to call a virtual function via a pointer, the compiler will generate code that:
Dereferences that pointer.
Gets the vtable pointer from the proper offset in that object
dereferences the vtable pointer to get the class' vtable
looks at the proper offset in the vtable to get a pointer to the function to invoke
invokes that function
Given a null pointer, step one of that process is going to break.
I'd note for the record that this applies to virtually all C++ compilers. VC++ is far from unique in this regard. Quite the contrary -- while it's theoretically possible for a compiler to implement virtual functions (for one example) differently than this, the reality is that every compiler of which I'm aware works essentially identically for the kind of code you posted. Virtually all C++ compilers will show similar behavior given the same code -- major differences in implementation are mostly a theoretical possibility, not one you're at all likely to encounter in practice.

When is the v-table created for a class?

I know that, how to implement virtual function call resolution is not part of C++ standrads nor it says anything about vptr or v-table, but let me ask this question here.
I've heard that v-table is a common technique used by compilers to implement virtual function call resolution. My understading about this is that there is only virtual table is needed per class, per process.
What I am wondering is, when is the v-table is created for a class?
Is it When the class of a given type (which needs a v-table) is created in a process space for the first time?
All other subsequently created objects of that type in that process space, refers to the v-table that is already created?
When would this v-table will be deleted?
I am sorry if this is too subjective or discussion type of question, but these questions lingers in my mind for a while and I feel its OK asking it here.
The v-table is statically allocated and is never deleted, nor is it explicitly allocated. The pointers within any given specific object are constants.
The C++ FAQ provides a simplified explanation of the vtable mechanism. You should give it a read, although you will probably have to go through your particular compiler documentation for more details.
The most important ideas from my point of view :
The vtable for a type is static and built at compile time
Each of the type instances contains a pointer to this table
Because this pointer is initialized at construction time, a virtual member function should never be called from the constructor
The vtable is static data so available immediately at load. BTW, it is usually bundled in the compilation unit which contains the definition for the first non-inline virtual function on the class (and that heuristic leads to problem when there is only one virtual function which is inline).
I believe it's all implementation defined, so it's difficultto give a universal answer to this question. I believe the vtable should be a some sort of a static class member.

How does a C++ object access its member functions?

How does a C++ object know where it's member function definitions are present? I am quite confused as the Object itself does not contain the function pointers.
sizeof on the Object proves this.
So how is the object to function mapping done by the Runtime environment? where is a class's member function-pointer table maintained?
If you're calling non-virtual functions, there's no need for a function-pointer table; the compiler can resolve the function addresses at compile-time. So:
A a;
a.func();
translates to something along the lines of:
A a;
A_func(&a);
Calling a virtual function through a base-class pointer typically uses a vtable. So:
A *p_a = new B();
p_a->func();
translates to something along the lines of:
A *p_a = new B();
p_a->p_vtbl->func(p_a);
where p_vtbl is a compiler-implemented pointer to the vtable specific to the actual class of *p_a.
There are generally two ways that an object and its member functions are associated:
For a non-virtual function, the compiler determines the appropriate function at compile time. Non-static member functions are usually passed a hidden parameter that contains the this pointer, which takes care of the association of the object and the class member function.
For virtual functions, most compilers tend to use a lookup table that is usually referenced via the object's this pointer or a similar mechanism. This table, normally called the vtable, contains the function pointer for the virtual functions only.
As C++ is not a dynamic language, the compiler can do most of the object/function/symbol resolution at compile time with the exception of some virtual functions. In some cases, it's even possible for the compiler to determine exactly which instance of a virtual function gets called and skip the resolution via the vtable.
Member functions are not part of the object - they are defined statically, in one place, just like any other function. There is no magic look-up needed.
Virtual functions are different, but I don't think your question is about that...
For non-virtual functions there is one (global, per-class) function table which all instances use. Since it's the same for all of them - deterministic at compile-time - you would not want it duplicated in each instance.
For virtual functions, resolution is done at runtime and the object will contain a function table for them. Try that and look at your object again.