vtable heuristic

Jason Merrill jason at cygnus.com
Thu Jul 15 09:20:16 UTC 1999


The heuristic I suggested in the meeting last week for limiting the
emission of vtables was to choose as a key the first non-abstract,
non-inline virtual function in the class, as with the typical heuristic,
and if that function should be redeclared as inline, just give up and emit
the vtable everywhere it's used.  But this variant is similarly fragile:

  foo.h:
  struct A {
    virtual void f ();
    virtual void g ();
  };

  foo.C:
  #include "foo.h"
  inline void A::f () { }
  void someotherfn () { }

  bar.C:
  #include "foo.h"
  void A::g () { }

  baz.C:
  #include "foo.h"
  int main()
  {
    A a;
  }

Here, both the typical heuristic and my suggested variant will break.  The
typical heuristic will see that f is now inline and decide to use g
instead.  But g doesn't know anything about that.  My suggestion breaks
similarly, because the vtable user in main() doesn't know that f is
inline.  But this code is ill-formed anyway; [basic.def.odr] says that a
virtual function is used if it is not pure, and an inline function must be
defined in every translation unit in which it is used, so A::f must be
defined in all three translation units for the code to be valid.

So I think the old heuristic is fine.

The problem our customer was having with the old heuristic was as follows:
They defined a proxy class in a shared library, and didn't export any of the
symbols of its members or vtable from the shared object.  The client called
some other API function to get a pointer to one of these objects, and called
one of its inline member functions.  This broke, because the compiler was
only emitting the inline functions for the class along with the vtable.  I
think it makes more sense to emit inlines where they are referenced, which
might be nowhere.

Jason




More information about the cxx-abi-dev mailing list