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