From 8641046303470407928
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,db4807a3f0a1e742
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 1994-08-03 04:38:02 PST
Newsgroups: comp.std.c++
Path: bga.com!news.sprintlink.net!hookup!usc!howland.reston.ans.net!EU.net!sun4nl!cwi.nl!olaf
From: olaf@cwi.nl (Olaf Weber)
Subject: Re: Multiple inheritance and delete
In-Reply-To: pkron@corona.com's message of Mon, 1 Aug 1994 21:50:00 PDT
Message-ID: <CtyIBt.4E7@cwi.nl>
Lines: 88
Sender: news@cwi.nl (The Daily Dross)
Nntp-Posting-Host: havik.cwi.nl
Organization: CWI, Amsterdam
References: <CtvC3r.5Kv@ucc.su.OZ.AU> <1994Aug02.045000.2253@corona.com>
Date: Wed, 3 Aug 1994 11:23:46 GMT

In article <1994Aug02.045000.2253@corona.com>, pkron@corona.com (Peter Kron) writes:

> The point here is whether non-polymorphic classes really add
> anything to the language--my position being that they create more
> potential for error than anything else.

There are two issues here: (1) should all classes be polymorphic with
respect to RTTI and destructor calls, and (2) should all member
functions of a class be virtual.

With repect to (1): there are ways of implementing this with little
run-time costs for people who don't use it.

The run-time cost incurred is related to finding the destructor to be
called in the absence of a virtual table: a single word per heap
object can be used to store the address of the destructor.  The time
overhead should vanish in the cost associated with the allocation
itself.  Whether the space overhead is bearable is a different matter.

The consequences of "RTTI for all" for executable size are perhaps
less pleasant, as some information needs to be available on the
lay-out of stack frames.  Howeverm, the same information could be
useful for exception handling, and perhaps also for garbage collection
or persistent objects, so the larger executable size might still be
considered affordable.

For (2) I think the answer should be no.  Use of call-by-reference in
combination with separate compilation means that many optimization
opportunities depend on knowing that no virtual call needs to be made.

As for having `virtual' rather than `nonvirtual', I still feel that
having to request the more expensive mechanism is the right thing.

> Concrete examples to the contrary would be illuminating here.

In the Standard Template Library, you'll find code like this:

	struct empty { };

	inline bool operator != (empty const &, empty const &)
		{ return true; }
	inline bool operator < (empty const &, empty const &)
		{ return false; }

	template <class Arg, class Result>
	struct unary_function: public empty {
		typedef Arg argument_type;
		typedef Result result_type;
	};

	template <class T>
	struct negate: public unary_function<T, T> {
		T operator () (T const & x) const
			{ return -x; }
	};

	template <class T>
	struct logical_not: public unary_function<T, bool> {
		bool operator () (T const & x) const
			{ return !x; }
	};

Here derivation is used to provide basic functionality to a large
number of classes without having to write it out for each of them.
It would be undesirable (for performance reasons) to let the member
functions be virtual in this example.

It could be argued that this is an abuse of inheritance, and that some
other mechanism should be used for this.  Macro hackery could probably
do the job, but the C++ preprocessor isn't the best tool.  [Insert ad
for the ARC++ macro facilities here].  Nor am I convinced that doing
this with macros is a superior technique.

> Non-polymorphic structs (ie, which override inherited, non-virtual
> member functions) are just as error prone as non-polymorphic
> classes.

This is an interesting definition of non-polymorphic structs.  If I
understand it correctly, the structs in the example above are not
non-polymorphic by that measure.

Now, does anybody actually _know_ how much of a problem C++'s ability
to override non-virtual member functions is?  I suspect that code that
uses that particular construct is very rare indeed.  If so, and if my
interpretation of what Peter Kron means by non-polymorphic is correct,
then it would seem that we are arguing a non-issue here.

-- Olaf Weber


