Why "inline" is incompatible with "virtual" - c++

Can someone explain the below paragraph please, no explanation is given:
The reason it works is that, in virtually all implementations of C++,
virtual functions are implemented with a "virtual function table",
which is an array of pointers to functions. This is incompatible
with function inlining because you simply can't have a pointer to
inline code. Thus for most situations, virtual and inline are incompatible; the compiler
will simply ignore the inline statement. However, there is one situation whereby they are
compatible: where the object is accessed directly instead of through a pointer.
"High Performance Game Programming in C++", Paul Pedriana
Can someone please explain why the two sentences in bold are so?

It simply means the compiler won't inline a call it has to resolve at run-time.
Suppose you have
struct A
{
virtual void foo() {};
};
and
void test(A* a)
{
a->foo();
}
This call is resolved at runtime. Since foo() could have been overriden by a deriving class and a could point to an object of a derived type, a->foo() can't be inlined - it will be resolved by a lookup.
The second statement means that virtual functions could be inlined in some situations:
void test(A a)
{
a.foo();
}
In this case, a is of type A (even if the original object passed to the function was a derived type, it was sliced because you passed by value) - the call is guaranteed to call A::foo so it can be inlined by the compiler.

First, the keywords aren't incompatible in any way. The paragraph is discussing the underlying implementation. A particular function call may be either inlined or go through a virtual dispatch, but usually not both. To understand why, you just need to understand what an inline call or a virtual call is.
An inlined function call is one where at least part of the called function is spliced directly into the calling function. This is a low-level optimization that the compiler may perform even on functions that aren't defined as inline. But in the early days when compilers were dumber and executable code size was more important, the keyword was more directly related to the optimization feature.
A virtual call is one where the caller doesn't know exactly what function will be executed. The function's implementation needs to be looked up (dispatched) according to the class at runtime.
So if the function will only be determined at runtime, the compiler cannot splice two functions together. It doesn't know what function would get spliced in.
But you can call a virtual function without making a special dispatch. This occurs if the compiler can be sure of the object's actual type at compile time. For example, if dog is derived from pet with a virtual method speak,
dog fido;
fido.speak(); // direct dispatch: we know fido is a dog.
But this is not the case if we have a reference:
bird buddy;
pet &favorite = prefer_dogs? fido : buddy;
favorite.speak(); // favorite may be a bird or dog: need virtual dispatch
Most of the time, when you call a virtual function you do so through a virtual dispatch.
There is another case, which as far as I know is only theoretical: if the compiler can be sure of the whole class hierarchy (or the choices in a given instance), it could add a Boolean test whether favorite is a bird or a dog and inline both function calls as alternatives in an automatically-generated if … else statement. But anyway, this is just nuts and bolts that you shouldn't worry about.
What's important is that a virtual function is called according to the type the object was defined as, and an inline function may be defined in a header file. And that's all that matters.

It is not "incompatible", just when actually virtual call is placed it is impossible to inline the unknown code. When static call is made to the function inlining will work alright.
The text is not very well formed, but if you already know what it wants to tell, you can find it there. ;-)

Related

Is virtual dispatch used if class type is known?

Suppose we have base class A with at least one virtual method. Suppose then we have another class B that derives from A and may or may not override this virtual method.
Finally, suppose you create an object of class B with local scope, and call this virtual method.
From the C++ docs we know that if this virtual method is inlined, the inline version will be used, because class type is known and this is not pointer or reference, but the class itself.
Will virtual dispatch be used in this case or it will be bypassed? Will this work for normal (non inline) methods?
I am interested in gcc / clang.
Since both the stack and the vtable are implementation details, it's probably better to phrase it:
Can the compiler use static - rather than virtual - dispatch if the object's (real, runtime) type is statically known?
to which the answer is: yes. Anywhere the compiler knows for certain what version of a virtual method will be used, it can just emit a regular statically-dispatched function call.
Note that there are some places you might expect the compiler to know the object's runtime type and be mistaken - specifically inside constructors.
If you want to know whether a particular compiler does emit this particular optimization for some particular code (at a particular optimization level), just check the assembly output. Even if you're not sure what both versions of a call should look like, you can compare the output with a simple and a fully-qualified call (b.B::foo() vs b.foo()). I'd expect gcc and clang to do a reasonable job in this case, but it's easy enough to check.

Inline and Virtual

guys. I have read several threads about the interaction between inline and virtual co-existing in one function. In most cases, compilers won't consider it as inline. However, is the principle applied to the scenario when a non-virtual inline member function call a virtual function? say:
class ABC{
public:
void callVirtual(){IAmVitrual();}
protected:
virtual void IAmVirtual();
};
What principle? I would expect the compiler to generate a call to the virtual function. The call (in effect a jump-to-function-pointer) may be inlined but the IAmVirtual function is not.
The virtual function itself is not inline, and it is not called with qualification needed to inline it even if it were, so it can't be inlined.
The whole point of virtual functions is that the compiler generally doesn't know which of the derived class implementations will be needed at run-time, or even if extra derived classes will be dynamically loaded from shared libraries. So, in general, it's impossible to inline. The one case that the compiler can inline is when it happens to know for sure which type it's dealing with because it can see the concrete type in the code and soon afterwards - with no chance of the type having changed - see the call to the virtual function. Even then, it's not required to try to optimise or inline, it's just the only case where it's even possible.
You shouldn't try to fight this unless the profiler's proven the virtual calls are killing you. Then, first try to group a bunch of operations so one virtual call can do more work for you. If virtual dispatch is still just too slow, consider maintaining some kind of discriminated union: it's a lot less flexible and cleanly extensible, but can avoid the virtual function call overheads and allow inlining.
All that assumes you really need dynamic dispatch: some programmers and systems over-use virtual functions just because OO was the in thing 20 years ago, or they've used an OO-only language like Java. C++ has a rich selection of compile-time polymorphic mechanisms, including templates.
In your case callVirtual() will be inlined. Any non-virtual function can be a good candidate of being inline (obviously last decision is upto compiler).
Virtual functions have to be looked up in the Virtual Method Table, and as a result the compiler cannot simply move them to be inline. This is generally a runtime look up. An inline function however may call a virtual one and the compiler can put that call (the code to look up the call in the VMT) inline.

How C++ object keeps information about its member functions

class A {
public :
void printSometext() {
std::cout << "printing A" << std::endl;
}
};
class B {
public :
void printSometext() {
std::cout << "printing B" << std::endl;
}
};
int main() {
A* a = new A();
a->printSometext();
return 0;
}
How C++ object keeps information about its member functions. Lets consider above code. When I call printSometext on object "a" how does it know what function to call and how it finds the right method.
When printing the size of the object it prints the summing size of its member variable (+allignments). So please provide some internal information how the member function call takes place.
Thanks,
Deimus
You have got the basics of C++ programming wrong. a does not know about printSomeText at the runtime, it is the compiler and linker which translates above code to binary code which performs these tasks. At runtime, there is just a bunch of instructions.
Well, that's an interesting question, but let me try to answer that in a very methodical manner !!!
let's say compiler has to resolve a call like this : *
a->someFunc();
*.
Now, compiler will go over following steps methodically.
1.) Firstly, compiler knows the declared type of variable a, so it will check whether the declared type of object a (lets call this, class A for time being), have a method with the name someFunc() and that it must be public. This method could either be declared in class A, or it could be a derived method from one of the base class(es) of class A, but it doesn't matter to compiler and it just checks for it's existence with it's access specifier being public.
Needless to say any error in this step will invite a compiler error.
2.) Secondly, once the method is validated to be a part of the class A, compiler has to resolve the call to the correct method, since many methods could be there with same name (thanks to function overloading). This process of resolving correct method is called overloading resolution. Compiler achieves this by matching the signatures of the called method with all the overloaded methods that are part of the class. So, of all the someFunc() s only the correct someFunc() (matching the signatures with called method) will be found and considered further.
3.) Now comes the difficult part, It may very well happen that someFunc() may have been overridden in one of the subclasses of the class A (lets call this class AA and needless to say it is some subclass of A), and that variable a (declared to be of type A) may actually be referring to an object of class AA, (this is permissible in C++ to enable polymorphism). Now, if the someFunc() method is declared to be of type virtual, in base class (i.e. Class A) and someFunc() has been overriden by subclass(es) of A (either in AA or classes between A and AA), the correct version of someFunc() have to be found out by the compiler.
Now, imagine you're the compiler and you have this task of finding whether the class AA has this method. Obviously, class AA will have this method since, it is a subclass of A and public access of A in class A has already been validated in Step 1 by the compiler !!! . But Alternatively, as mentioned in previous paragraph, someFunc() may be overriden by class AA (or any other class between A and AA), which is what compiler needs to catch. Therefore, you (since, your'e playing the compiler) could do a systematic check to find the bottom-most (lowest in the inheritance tree) overridden method someFunc() starting from class A and ending at class AA. In this search, you'll look for same method signatures as was validated in overloading resolution. This method will be the method which will be invoked.
Now, you may be wondering, "What the heck", is this search done everytime ? ... Well, Not really. The compiler knows the overhead of finding this everytime, and as such, maintains a data-structure called Virtual Table for every class type. Think of virtual table, as mapping from method signatures (which are publicly accessible) to the function pointers. This virtual table is made by compiler during compilation process and is maintained in-memory during program execution. In our example, class A and class AA will both have their own virtual tables. And when compiler has to be find someFunc() in class AA (since actual object pointed by variable a is of type AA), it will simply find the function pointer through the virtual table of Class AA. This is as simple has hashing into the table and is a constant time operation.
Regards
AViD
Adding to the Asha's answer (+1):
If you really want to understand how stuff works internally, I suggest to learn assembly and explore the generated machine code. That's what I did.
The compiler knows the types of the variables. When you use the
. or the -> operator, it looks up the symbol to the left in the
context of the class type of the right hand argument. So in
your example, it only finds A::printSomeText.
--
James Kanze

inline virtual function

In C++, my understanding is that virtual function can be inlined, but generally, the hint to inline is ignored. It seems that inline virtual functions do not make too much sense.
Is that right?
Can anybody give a case in which an inline virtual function is good?
In order to answer this question fully, one needs to understand that the property of being virtual applies independently to the function itself and to the calls made to that function. There are virtual and non-virtual functions. There are virtual and non-virtual calls to these functions.
The same is true about the property of being inline. There are iniline and non-inline functions. And there are inlined and non-inlined calls to these functions.
These properties - virtual and inline - when applied to the function itself, do not conflict. They simply have no reason and no chance to conflict. The only thing that inline specifier changes for the function itself is that it modifies the One Definition Rule for that function: the function can be defined in multiple translation units (and it has to be defined in every translation unit where it is used). The only thing virtual specifier changes is that the class containing that function becomes polymorphic. It has no real effect on the function itself.
So, there's absolutely no problem in declaring a function virtual and inline at the same time. There's no basis for the conflict whatsoever. It is perfectly legal in C++ language.
struct S {
virtual void foo();
};
inline void S::foo() // virtual inline function - OK, whatever
{
}
However, when people are asking this question, they are usually not interested in the properties of the function itself, but rather in characteristics of the calls made to the function.
The defining feature of a virtual call is that it is resolved at run time, meaning that it is generally impossible to inline true virtual calls:
S *s = new SomeType;
s->foo(); // virtual call, in general case cannot be inlined
However, if a call is by itself non-virtual (even though it goes to a virtual function), inlining is not a problem at all:
S *s = new SomeType;
s->S::foo(); // non-virtual call to a virtual function, can easily be inlined
Of course, in some cases an optimizing compiler might be able to figure out the target of a virtual call at compile time and inline even such virtual call. In some cases it is easy:
S ss;
ss.foo(); // formally a virtual call, but in practice it can easily be inlined
In some cases it is more complicated, but still doable:
S *s = new S;
s->foo(); // virtual call, but a clever compiler might be able
// to figure out that it can be inlined
Under normal circumstances, a virtual function will be invoked via a pointer to a function (that's contained in the class' vtable). That being the case, a virtual function call can only be generated inline if the compiler can statically determine the actual type for which the function will be invoked, rather than just that it must be class X or something derived from X.
The primary time an inline virtual function makes sense is if you have a performance critical situation, and know that a class will frequently be used in a way that allows the compiler to determine the actual type statically (and at least one target compiler optimizes out the call via pointer).
You can have virtual functions as inline. The decision to make the function call inline is not just made at the compile time. It could be anytime between compilation to rutime. You can refer to this article from Herb Sutter. Inline Redux

If classes with virtual functions are implemented with vtables, how is a class with no virtual functions implemented?

In particular, wouldn't there have to be some kind of function pointer in place anyway?
I think that the phrase "classes with virtual functions are implemented with vtables" is misleading you.
The phrase makes it sound like classes with virtual functions are implemented "in way A" and classes without virtual functions are implemented "in way B".
In reality, classes with virtual functions, in addition to being implemented as classes are, they also have a vtable. Another way to see it is that "'vtables' implement the 'virtual function' part of a class".
More details on how they both work:
All classes (with virtual or non-virtual methods) are structs. The only difference between a struct and a class in C++ is that, by default, members are public in structs and private in classes. Because of that, I'll use the term class here to refer to both structs and classes. Remember, they are almost synonyms!
Data Members
Classes are (as are structs) just blocks of contiguous memory where each member is stored in sequence. Note that some times there will be gaps between members for CPU architectural reasons, so the block can be larger than the sum of its parts.
Methods
Methods or "member functions" are an illusion. In reality, there is no such thing as a "member function". A function is always just a sequence of machine code instructions stored somewhere in memory. To make a call, the processor jumps to that position of memory and starts executing. You could say that all methods and functions are 'global', and any indication of the contrary is a convenient illusion enforced by the compiler.
Obviously, a method acts like it belongs to a specific object, so clearly there is more going on. To tie a particular call of a method (a function) to a specific object, every member method has a hidden argument that is a pointer to the object in question. The member is hidden in that you don't add it to your C++ code yourself, but there is nothing magical about it -- it's very real. When you say this:
void CMyThingy::DoSomething(int arg);
{
// do something
}
The compiler really does this:
void CMyThingy_DoSomething(CMyThingy* this, int arg)
{
/do something
}
Finally, when you write this:
myObj.doSomething(aValue);
the compiler says:
CMyThingy_DoSomething(&myObj, aValue);
No need for function pointers anywhere! The compiler knows already which method you are calling so it calls it directly.
Static methods are even simpler. They don't have a this pointer, so they are implemented exactly as you write them.
That's is! The rest is just convenient syntax sugaring: The compiler knows which class a method belongs to, so it makes sure it doesn't let you call the function without specifying which one. It also uses that knowledge to translates myItem to this->myItem when it's unambiguous to do so.
(yeah, that's right: member access in a method is always done indirectly via a pointer, even if you don't see one)
(Edit: Removed last sentence and posted separately so it can be criticized separately)
Non virtual member functions are really just a syntactic sugar as they are almost like an ordinary function but with access checking and an implicit object parameter.
struct A
{
void foo ();
void bar () const;
};
is basically the same as:
struct A
{
};
void foo (A * this);
void bar (A const * this);
The vtable is needed so that we call the right function for our specific object instance. For example, if we have:
struct A
{
virtual void foo ();
};
The implementation of 'foo' might approximate to something like:
void foo (A * this) {
void (*realFoo)(A *) = lookupVtable (this->vtable, "foo");
(realFoo)(this); // Make the call to the most derived version of 'foo'
}
The virtual methods are required when you want to use polymorphism. The virtual modifier puts the method in the VMT for late binding and then at runtime is decided which method from which class is executed.
If the method is not virtual - it is decided at compile time from which class instance will it be executed.
Function pointers are used mostly for callbacks.
If a class with a virtual function is implemented with a vtable, then a class with no virtual function is implemented without a vtable.
A vtable contains the function pointers needed to dispatch a call to the appropriate method. If the method isn't virtual, the call goes to the class's known type, and no indirection is needed.
For a non-virtual method the compiler can generate a normal function invocation (e.g., CALL to a particular address with this pointer passed as a parameter) or even inline it. For a virtual function, the compiler doesn't usually know at compile time at which address to invoke the code, therefore it generates code that looks up the address in the vtable at runtime and then invokes the method. True, even for virtual functions the compiler can sometimes correctly resolve the right code at compile time (e.g., methods on local variables invoked without a pointer/reference).
(I pulled this section from my original answer so that it can be criticized separately. It is a lot more concise and to the point of your question, so in a way it's a much better answer)
No, there are no function pointers; instead, the compiler turns the problem inside-out.
The compiler calls a global function with a pointer to the object instead of calling some pointed-to function inside the object
Why? Because it's usually a lot more efficient that way. Indirect calls are expensive instructions.
There's no need for function pointers as it cant change during the runtime.
Branches are generated directly to the compiled code for the methods; just like if you have functions that aren't in a class at all, branches are generated straight to them.
The compiler/linker links directly which methods will be invoked. No need for a vtable indirection. BTW, what does that have to do with "stack vs. heap"?