2

If I create a very simple class like this :

class A
{
  public :
    virtual void foo()
    {
    }
};

(no virtual destructor) is the compiler going to create vtable? Or are modern compilers smart enough to recognize this case (which might be a bad copy and paste) and not add virtual table for such classes?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • A common techniques is to emit the vtable with the first virtual non inline member. I don't know what's the fallback in case like this where there is virtual non-inline members, but that isn't a worse problem to solve than static in inline functions or template instantiation. – AProgrammer Apr 11 '11 at 13:49
  • 2
    The virtual destructor is just one way of forcing the class to be polymorphic, if there happens to be no other virtual functions. (It is also a needed if you intend to delete derived classes through a pointer to A). – Bo Persson Apr 11 '11 at 13:53
  • 3
    @AProgrammer - The compiler will probably have to produce lots of copies of the vtable, and have the linker sort it out. – Bo Persson Apr 11 '11 at 13:57

3 Answers3

5

The v-table is an implementation detail. Compilers that use v-tables for virtual functions will create one for this class. Those that don't, won't.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • 1
    what are some of the alternatives? – Jason S Apr 11 '11 at 13:34
  • @Jason: See [this question](http://stackoverflow.com/questions/4352032/a-question-about-virtual-mechanism-in-c) and [this one](http://stackoverflow.com/questions/5417829/how-can-c-virtual-functions-be-implemented-except-vtable) – Ben Voigt Apr 11 '11 at 13:35
  • You are right that it is an implementation detail, but are there modern compilers not doing it that way? – BЈовић Apr 11 '11 at 13:40
  • @VJo: I'm going to refer you to the same two questions I linked for Jason. They've now appeared to the right of your question under the heading "Linked" as well as links in my comment above. – Ben Voigt Apr 11 '11 at 13:44
2

The compiler cannot be sure that the class is not derived in another compilation unit, so it has to ensure that the call is correctly dependent on runtime type of the instance.

If it use a vtable to resolve virtual call, then a vtable will be created. If another implementation is used, then the mechanism will be used.


Old version: A vtable will be created since the compiler can't be sure that the class will not be derived in another compilation unit.

Sylvain Defresne
  • 42,429
  • 12
  • 75
  • 85
  • The compiler will set up the machinery to make virtual calls work as required by the standard. That machinery might not be a vtable. – Ben Voigt Apr 11 '11 at 13:32
1

The answer is that the compiler will have to generate a v-table. To understand why consider:

class B : public A
{
    void foo() { do something interesting }
}

And somewhere else:

void bar (A& obj)
{
obj.foo()
}

One can surely pass an object of type B to bar() and the B::foo() will be called. It is good programming practice to always have a virtual destructor for all polymorphic classes because is allows one to polymorfically delete A. In our case where obj is of type B

void bar2 (A& obj)
{
delete obj;
}

will probably not behave as expected because the destructor for B will never be called.

doron
  • 27,972
  • 12
  • 65
  • 103