[gnu.g++] On class data and alternatives to +e0/+e1

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