grunwald@flute.cs.uiuc.edu (03/17/89)
Rather than follow the steps of AT&T C++ in the use of +e0 and +e1, I think that the time has come for G++ to take a (backwards compatible) step away from C++. The problem solved (poorly) by +e0/+e1 is basically one of class-data, as opposed to class-instance-data. The reason it's a problem is that C++ is very flexible about the idea of a ``module''. This makes it difficult to determine where to leave vtables, and also bodies for virtual inline functions. Consider the addition of a single #pragma (please, don't blech yet). For example, for class LinkedList, I might put the following in LinkedList.cc: #pragma class instance LinkedList At this point, G++ would say `aha - this is the file in which I put the unique instance of the vtable'. This solves the same problem that +e0/+e1 does, but does it in a much cleaner way. Recognition of the #pragma would be determined by a compiler flag. If you don't set the flag, the previous rules are used (private vtables, etc). Thus, if a user of a library forgets to set the flag when they compile, there's no problem (this is true for +e0/+e1 as well). But the maintenance and use of library code is made significantly easier. This would also resolve the use of definitions for virtual inline functions. Consider: class A { virtual foo() }; class B : public A { virtual foo() }; If I have the following fragment: B b; b::foo() then I know I can directly call B::foo(), and it could be an inline, even if it was declared virtual. If I have B *ptr; ptr -> foo() I can't inline foo, and I need to have a code body sitting around to fill in the vtable entry. In this case, I'd like to have *one* code body, other wise, I'd break most debuggers (i.e. setting a breakpoint would require setting it in *all* instances of the code body). The +e0/+e1 hack doesn't address this issue, because it applies to a specific *file*, not a specific *class*. The advantages of this are clear: + it allows single vtables, simplifying the management of libraries at the same time. + it allows virtual inlines to be fully implemented. + the same technique could be used to provide instance of non-virtual inlines that are judged to be ``too big'' to be inlined. + it's relatively backwards compatible (at least as compatible as +e0/+e1, and possible more so). If you port your code to another C++ system that doesn't use the #pragma, things still work. + It's as easy (or easier) to implement than +e0/+e1. The down-sides: + it required all virtual inlines to be ``visible'' in the file that contains the #pragma, in order for there to be a single instance of those inlines. So, whatt'ya think? Reasonable addition? Dirk Grunwald Univ. of Illinois grunwald@flute.cs.uiuc.edu -- Dirk Grunwald Univ. of Illinois grunwald@flute.cs.uiuc.edu