TITLE: Cfront generation of vtables PROBLEM: sfc@datascope.com (Steve F. Cipolli) Can anyone tell me if there has been any improvement in cfront's virtual table generation mechanism. I am aware of the +e0, +e1 options. RESPONSE: clamage@taumet.Eng.Sun.COM (Steve Clamage), 7 Jul 94 The +e0 and +e1 options allow you to force (+e1) or prevent (+e0) generation of vtables in a given compilation unit. You don't even need to know about these flags for ordinary programming. Since about 1990 cfront (among other compilers) has used a heuristic to avoid duplicated vtables: The compiler emits an external definition of the vtable in the module containing the definition (body) of the first non-inline non-pure virtual function in the class. Example: class X { int f1(); // not virtual virtual int f2() { return 0; } // virtual, but inline virtual int f3() = 0; // pure virtual virtual int f4(); // THIS IS IT virtual int f5(); // non-pure non-inline virtual but not the first }; The compilation unit which contains the definition of X::f4() will also contain the vtable for class X. Any other compilation unit which needs to access the vtable will generate only an external reference to it, trusting the linker to find the vtable. The One-Definition Rule requires that all definitions of class X match, so this heuristic is safe for all conforming programs. The alert reader will note that if you neglect to provide a definition for X::f4() -- perhaps because you are still developing the program and have no code which calls it yet -- the vtable will not be generated. On probably all systems, your program won't link anyway if any virtual functions are missing, so this isn't a limitation. What if a class has virtual functions but they are all inline or pure? The usual solution is to generate a static copy of the vtable in every compilation unit which contains a definition of a constructor for X. This situation occurs seldom, and the wasted memory is not usually a problem. If it is, you can use the +e0 and +e1 (or equivalent) flags. Borland has another solution (perhaps others use it too). BC++ (and TC++) uses its own object file format and linker. The object file format has a special address section which allows multiple definitions of global objects, something normally an error. The compiler emits an external definition of X's vtable in each module containing a constructor definition for X, but puts the definition in this special address section. At link time, the linker discards all but one of the copies of the X vtable, and adjusts references in all modules to point to the one copy. Individual object files may be a bit larger than they would otherwise be, but the linked executable never has duplicated vtables.