[comp.lang.c++] C++ binary classes

niklas@appli.se (Niklas Hallqvist) (04/07/91)

chip@tct.com (Chip Salzenberg) writes:

>According to kelley@mpd.tandem.com (Michael Kelley):
>>In article <27F77834.16D6@tct.com>, chip@tct.com (Chip Salzenberg) writes:
>>> Sorry; typeof() is neither necessary nor sufficient.
>>> 
>>> Not necessary: because a virtual freeze_on() function for each type
>>> can be written.  It's a bit of a pain, yes, but it can be done.
>>
>>True, provided *you* implement the class.  What happens when you get a class
>>library from vendor X ...

>This kind of problem is why I expect attempts at distribution of
>binary-only C++ classes to have, at best, limited success.

>C++ requires _everything_ about a class to be in one place, namely,
>the class definition.  In particular, all member functions must be
>declared there.  Forbidding users to change the class definitions is
>too tight a straightjacket for me to impose on them.  (Remember that,
>in current C++ implementations, adding virtual functions requires the
>recompilation of all constructors.)

So, what is required for distribution of binary only C++ classes that are
to be extensible by inheritance and adding virtual functions?  Source code
for the constructors?  The class definition of course (in source form, but
I believe no (or almost none) C++ compiler supports precompiled headers). 
I understand that extending the class with extra data members won't work,
but that's what inheritance are for, isn't it?  As I see it, this should
be of little concern to C++ class developpers, since no work worth
protecting should reside in constructors.

Well, there is some problems here.  Adding virtual functions might change
the original vtable (I speak only about the usual vtable implementation
here) in a non-backward compatible way, namely rearranging the vtable
slots.  This may cause unpredictable errors because wrong functions
being called by compiled-only callers in the original C++ class.  Should
there be a way to ensure backward compatibility when adding virtuals?
I don't know, but if it makes binary-only distributions easier, lots of
other people would definitely say so.  IMHO, the easiest way to do this would
be that ANSI ensures the following: Suppose there is a class B having exactly
all the members and base classes that another class A has except for some
additional virtual functions, and those members and bases are defined in
exactly the same order in both classes, plus the fact that any additional
virtuals in B are defined after the ones common with A.  Now a virtual
function call of an object of type B should behave as if B was singly
non-virtually derived from A only adding those virtuals.  At least I think
this would suffice.  Is this so?  Another problem is that no constructors
from the original library could be inline expanded in the binary components,
but that is of course easily dealt with as long as you can ensure that an
optimizing compiler won't do that without your knowledge.  Have I missed
something important in my reasoning here? Supposing I'm correct, is this
change to the language rules wortwhile?

						Niklas
-- 
Niklas Hallqvist	Phone: +46-(0)31-40 75 00
Applitron Datasystem	Fax:   +46-(0)31-83 39 50
Molndalsvagen 95	Email: niklas@appli.se
S-412 63  GOTEBORG, Sweden     mcsun!sunic!chalmers!appli!niklas

steve@taumet.com (Stephen Clamage) (04/09/91)

niklas@appli.se (Niklas Hallqvist) writes:

>So, what is required for distribution of binary only C++ classes that are
>to be extensible by inheritance and adding virtual functions?  Source code
|for the constructors?  The class definition of course (in source form, but
|I believe no (or almost none) C++ compiler supports precompiled headers). 
|I understand that extending the class with extra data members won't work,
|but that's what inheritance are for, isn't it?  As I see it, this should
|be of little concern to C++ class developpers, since no work worth
|protecting should reside in constructors.
|...
|Another problem is that no constructors
|from the original library could be inline expanded in the binary components,
|but that is of course easily dealt with as long as you can ensure that an
|optimizing compiler won't do that without your knowledge.  Have I missed
|something important in my reasoning here? Supposing I'm correct, is this
|change to the language rules wortwhile?

There are still problems.  If a class does not have an explicit non-inline
null constructor X::X(), copy constructor X::X(X&), and assignment
X::operator=(X&), the compiler may have used default inline versions of
these in internal library code, which would become invalid if the class
definition changed.

It is just not a good idea to modify class definitions without recompiling
all code which uses those definitions.  This probably limits the
usefulness of binary-only libraries.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

davidm@uunet.UU.NET (David S. Masterson) (04/10/91)

>>>>> On 9 Apr 91 15:38:47 GMT, steve@taumet.com (Stephen Clamage) said:

Stephen> It is just not a good idea to modify class definitions without
Stephen> recompiling all code which uses those definitions.  This probably
Stephen> limits the usefulness of binary-only libraries.

What if there were two layers to C++ libraries of objects?  The first
(innermost) layer is the core of the object and knows how to really perform
each method.  The second is really just a wrapper for the first that doesn't
show any details of the first to users of the second.

Can this be accomplished with C++?  Would it be useful?  Would there be too
much overhead to make this viable?  Just kicking an idea around.
--
====================================================================
David Masterson					Consilium, Inc.
(415) 691-6311					640 Clyde Ct.
uunet!cimshop!davidm				Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"