0

Possible Duplicate:
Pure virtual functions may not have an inline definition. Why?

Just as the title says, why? And how about (not pure) virtual function, can it be inline format? And I'd like to know the real reason. Thanks!

Community
  • 1
  • 1
Tom Xue
  • 3,169
  • 7
  • 40
  • 77
  • Did you mean to ask whether the function body can be provided inside the class definition? Because that's only one of two ways to make a member function `inline`, and the other still works. – Ben Voigt Jan 02 '13 at 13:25

2 Answers2

6

A virtual function 99% of the time cannot be inlined because the function pointer is resolved at runtime using vtable.

The purpose of a virtual function is to be overloaded by subclasses. An example :

class A
{
    virtual int foo() { return 1; }
}

class B : public A
{
    virtual int foo() { return 2; }
}

int main(void)
{
    B b;
    A *a = &b;

    return a->foo();
}

The main function will return 2 and not 1.

If the compiler inline the function it will return 1 because the compiler can only assume that the type of *a is A and not B. So the compiler will not do it if he cannot assume safely the type of *a.

In this example the compiler may successfully and safely assume that virtualization is not needed : This is really depending of the compiler and of optimization level.

In some case the compiler can safely assume that virtualization is not needed and only in these cases the inline keyword makes sense.

Even if you declare a function with the keywords inline, the function may not be inlined.

Anyway adding manually the inline keyword is most of the time not a good idea, compiler today are good and automatically inline function when necessary. By adding inline you may in some case decrease performance, so it a good practice to not abuse of it

benjarobin
  • 4,410
  • 27
  • 21
  • Can you clarify your answer - are you saying virtual functions cannot be declared inline or are you saying that even if they are declared inline, they will not be inlined? – user93353 Jan 02 '13 at 13:12
  • *Devirtualization* of function calls is a well-known optimization, and can be combined with inlining. Inlining is also enabled by *speculative devirtualization*. – Ben Voigt Jan 02 '13 at 13:17
  • @benjarobin I inline foo() in both class A and B, but the return value of main() is still 2, why? – Tom Xue Jan 03 '13 at 05:18
  • You did not inlined the function, you add the keyword inline, this is something different. But here the example is too simple, gcc may be able to understand the real type of a pointer – benjarobin Jan 03 '13 at 08:29
2

Well, a pure virtual function certainly can be marked inline.

struct Base
{
    virtual void Func() const = 0;
};

inline void Base::Func() const
{ std::cout<<"Base\n"; }

struct Concrete : Base
{
    virtual void Func() const;
};

inline void Concrete::Func() const
{ Base::Func(); std::cout<<"Concrete\n"; }

Also, virtual functions can be inlined (which is not very closely related to the inline keyword) in cases where the compiler can statically determine the function that needs to be called. For example:

int main(void)
{
    Concrete o;
    o.Func();
}

Complete demo: http://ideone.com/zlxn8I

And see this related question: LTO, Devirtualization, and Virtual Tables

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720