From 3264196964805777404
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,db4807a3f0a1e742
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 1994-07-18 06:43:25 PST
Path: bga.com!news.sprintlink.net!redstone.interpath.net!ddsw1!panix!MathWorks.Com!europa.eng.gtefsd.com!howland.reston.ans.net!usenet.ins.cwru.edu!news.ecn.bgu.edu!psuvax1!news.pop.psu.edu!news.cac.psu.edu!newsserver.jvnc.net!yale.edu!xlink.net!scsing.switch.ch!swidir.switch.ch!newsfeed.ACO.net!Austria.EU.net!EU.net!uunet!news.centerline.com!news!immel
From: immel@chord.centerline.com (Mark Immel)
Newsgroups: comp.std.c++
Subject: Re: Multiple inheritance and delete
Date: 18 Jul 1994 13:22:30 GMT
Organization: CenterLine Software, Inc.
Lines: 64
Message-ID: <IMMEL.94Jul18092230@chord.centerline.com>
References: <IMMEL.94Jul15110950@chord.centerline.com>
NNTP-Posting-Host: chord.centerline.com
In-reply-to: immel@chord.centerline.com's message of 15 Jul 1994 15:09:50 GMT


C++ gurus and standard committee --

I asked about the following code a few days ago.  The problem is that the
call to delete b calls free with a bad address; this is a particularly nasty
silent failure -- often the program will crash much later.  Many of you
commented that giving B a virtual destructor will fix the problem; that's
true.  However, the WP 5.3.5 (26 May, 1994 version) implies that my code
is legal:


	struct A {};
	struct B {};
	struct C: A, B {};

	void foo()
	{
	  B* b = new C;
	  delete b;
	}

5.3.5 paragraph 2:

  "The value of the operand of delete must be a pointer to a non-array
   object created by a new-expression without a new-placement specification,
   or a pointer to a subobject representing a base class of such an object."

5.3.5 paragraph 3:

  "If the static type of the operand is different from its dynamic type *AND 
   THE CLASS OF THE COMPLETE OBJECT HAS A DESTRUCTOR*, the static type must 
   have a virtual destructor, or the result is undefined." (emphasis mine)

Mr. Hartmut Kocher has been courteous enough to send me his thoughts on the
issue -- he would like to see the WP altered to remove the emphasized type,
I believe (if I have misstated his position, I apologize).  Then, B would
have to have a virtual destructor and all would be well.  

Another possibility is:

  "If the static type of the operand is different from its dynamic type, and
   the class of the complete object has multiple inheritance anyplace, the 
   static type must have a virtual destructor, or the result is undefined."

However, neither of these is easy to statically check (BTW neither is the
correct WP wording, and this is a nasty bug that I would like my compiler
to nail me for).  Compilers could generate warnings, most of which would
be spurious, about deleting classes without virtual destructors; we would
ignore them all and miss the few that were real trouble.  I think 
there are two reasonable options:

1) Require a compiler diagnostic if multiple inheritance is used and at least
   one direct or indirect base class does not have a virtual destructor.

2) (Preferably) use the RTTI information mandated in the standard to convert
   the B* to a C* before it goes off to delete; the language now mandates 
   that the type information be around anyhow.  This may be the intention in
   the WP; but it should say so explicitly so that compiler implementors 
   realize this.

-- Mark Immel
   immel@centerline.com

(You may email me if convenient -- I will summarize)


