Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!cornell!rochester!pt.cs.cmu.edu!pt!dld From: dld@F.GP.CS.CMU.EDU (David Detlefs) Newsgroups: comp.lang.c++ Subject: Re: Multiple inclusion of virtual tables... Message-ID: Date: 20 Mar 89 17:37:14 GMT Organization: CMU CS Department Lines: 97 In article 2970, Dirk Grunwald suggests an alternative to the +e0/+e1 method of cutting down on the number of vtables in programs. His suggestion is that programmers insert #pragma class instance Foo in the .c file corresponding to the .o file in which the programmer wishes the vtable (and bodies of inline functions) be defined. I would like to suggest a slight variation on this theme that I've implemented here at CMU. It's much like the above, except that at class declaration time I choose a distinguished non-inline member function, and use the implementation of that distinguished member function as a marker for where the vtable should be defined. (I don't at present insert bodies for virtual functions, but adding that should be easy; similarly, if the semantics of the language were modified, static member initialization could be done here as well.) In my implementation, I choose the first non-inline member-function name in alphabetic order (being carful to use fully expanded names of overloaded functions.) Pro: Just as with Mr. Grunwald's suggestion, each class gets exactly one vtable. Vtables for classes in libraries are in the .o's in the .a, where common sense says that they belong. The added value of my scheme (which I'm sure has been thought of many times before by others) is that in most cases, it does the right thing with absolutely no programmer effort. Cons: bad things about this are: 1) it doesn't work for classes that have no non-inline functions, 2) if a member function is not declared inline in the class declaration, it may be chosen as the distinguished member function. If an inline definition for that function is given later on in the .h file, things break. 3) you have to link your program with all .o files that contain implementations of member functions for classes used in the program. 3) Is not a big restriction, I think. Most people generally follow a "one .h, one .c per class" protocol. This is especially not a problem for libraries, where all the .o's for a class will be in the .a. It would be good if linkers could be modified to produce a suggestive error message whenever a vtable if found to be undefined. 2) is easy to "solve." Just change the language :-) Seriously, the only way around this I can think of would be to make it illegal to include an inline implementation of a member function outside a class declaration unless the member function had been declared inline in the declaration. That is class foo { int i; public: void bar(); }; inline void foo::bar() { i++; }; would be illegal, and would have to be fixed to say class foo { int i; public: inline void bar(); // <--- Note inline. }; inline void foo::bar() { i++; }; This would require some modification of existing C++ code, but note that the result would be equivalent to the code you started with. You could further reduce the impact by only making it an error for classes with virtual functions. I plan to further hack our local version of cfront to produce this error message. 1) Can be solved by using "main" as the distinguished function for all classes with nothing but virtual functions. This would require that all .h files defining such classes be included by the .c file that contains "main," in much the way that the .c file that is compiled using +e1 must include all the .h files used by the program in the +e0/+e1 paradigm. To sum up, I think: +e0/+e1 is a hack (albeit a necessary one at the time), so something like Mr. Grunwald's suggestion or the one I've outlined above should probably be used instead. In many ways Mr. Grunwald's suggestion is cleaner, but this one seems to work in almost all cases without anyone other than the compiler-writer having to do anything. Comments are of course welcome, and anyone who wants to use this idea is of course free to do so (unless it's not original with me and someone has copyrighted it or something :-). -- Dave Detlefs Any correlation between my employer's opinion Carnegie-Mellon CS and my own is statistical rather than causal, dld@cs.cmu.edu except in those cases where I have helped to form my employer's opinion. (Null disclaimer.) --