Thread View: comp.std.c++
13 messages
13 total messages
Started by Chris Parker
Thu, 09 Nov 1995 06:08
Virtual functions and destructors
Author: Chris Parker
Date: Thu, 09 Nov 1995 06:08
Date: Thu, 09 Nov 1995 06:08
32 lines
2089 bytes
2089 bytes
As a result of problems I'm having with C++ program execution, I need to examine what the C++ standard says with respect to virtual destructors. I understand these are a special case of virtualness and there are special rules associated with how compilers are to support them. Does C++ require you to declare your destructor virtual whenever you declare any other member function in the class to be virtual? Is it acceptable according to the standard for the destructor to be the only virtual member in the class? Is virtualness inherited by destructors? Does C++ automatically make all applicable superclasses also have virtual destructor if they don't already? If virtualness of destructors is inherited, then what is supposed to happen to in the case where one of our subclasses uses multiple inheritance and one of the other trees leading to the subclass doesn't declare destructors to be virtual anywhere? If anyone has any knowledge regarding what the C++ standard says about virtual destructors, I'd appreciate it if you could answer any of the questions that you can. I have all these situations occuring in a program I wrote, and I don't understand why it is behaving as it is and the answers to those questions would explain a lot of things for me. Thanks for any input you can provide. Chris Parker parker@cs.WPI.EDU --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Alex Martelli
Date: Thu, 09 Nov 1995 19:33
Date: Thu, 09 Nov 1995 19:33
73 lines
2816 bytes
2816 bytes
parker@WPI.EDU (Chris Parker) writes:
...
>Does C++ require you to declare your destructor virtual whenever you declare
>any other member function in the class to be virtual?
I see no words in the draft standard to this effect.
>Is it acceptable according to the standard for the destructor to be the only
>virtual member in the class?
I see nothing in the draft standard forbidding this.
>Is virtualness inherited by destructors? Does C++ automatically make all
>applicable superclasses also have virtual destructor if they don't already?
Inheritance flows _downwards_ -- a superclass's characteristics (in
particular, whether its dtor is or isn't virtual) is never changed by
some other class inheriting from it.
>If virtualness of destructors is inherited, then what is supposed to happen to
>in the case where one of our subclasses uses multiple inheritance and one
>of the other trees leading to the subclass doesn't declare destructors to be
>virtual anywhere?
If that subclass is destroyed through a pointer to an ancestor whose
dtor isn't virtual, undefined behaviour (violation of a "shall").
E.g.:
class A {public: virtual ~A()};
class B {public: ~B()}; // NON-virtual dtor
class C: public A, public B {};
int main()
{
A* a=new C; // ok
B* b=new C; // also ok
delete a; // fine!
delete b; // undefined behaviour
return 0;
}
I _think_ the following is supposed to be fine ("inherited virtualness
of dtor") but I can't find words in the draft standard that SAY so...:
class A {public: virtual ~A();}
class B: public A {}; // no _explicit_ dtor...
class C: public B {};
int main()
{
A* a=new C; //
delete a; // this is surely OK, but...
B* b=new C; //
delete b; // ...I _think_ this is supposed to be OK too...?
return 0;
}
Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia Fax: +39 (51) 597120
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Chris Parker
Date: Fri, 10 Nov 1995 05:18
Date: Fri, 10 Nov 1995 05:18
35 lines
2452 bytes
2452 bytes
In article <martelli.815930692@cadlab> martelli@cadlab.it (Alex Martelli) write
s:
>
>>Is virtualness inherited by destructors? Does C++ automatically make all
>>applicable superclasses also have virtual destructor if they don't already?
>
>Inheritance flows _downwards_ -- a superclass's characteristics (in
>particular, whether its dtor is or isn't virtual) is never changed by
>some other class inheriting from it.
Alex,
Yeah, I know what you're saying, but I think when the function is the
destructor we should consider it differently. Normally, when you destroy
an object, each destructor up the parentage tree gets executed in order from
child to parent. In a strange kind of way, it behaves somewhat virtually
on its own.
May I inquire when you would ever *not* want the destructor to be virtual?
Probably only in the leaf of the class heirarchy. Destroying the object above
the leaf child without having a virtual destructor causes nothing but a memory
leak, and quite possibly pain and hardship. When you free an object, you
really need to free it as what it really is, not what it looks like it is.
The only disadvantage of this is there is price to pay at runtime when
freeing the object because we need to find the destructor function through
dynamic binding. So, I propose that if that if at any point in a class
heirarchy tree a destructor is declared virtual, all destructors in the tree
are virtual because that is really what you are trying to ask for. What
do you think?
Chris Parker
cparke@sapient.com
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Alex Martelli
Date: Fri, 10 Nov 1995 19:21
Date: Fri, 10 Nov 1995 19:21
64 lines
2760 bytes
2760 bytes
parker@WPI.EDU (Chris Parker) writes:
...
> The only disadvantage of this is there is price to pay at runtime when
>freeing the object because we need to find the destructor function through
And a space cost that can be huge.
>dynamic binding. So, I propose that if that if at any point in a class
>heirarchy tree a destructor is declared virtual, all destructors in the tree
>are virtual because that is really what you are trying to ask for. What
>do you think?
Consider:
class Point {
unsigned short x, y;
public:
// nonvirtual methods
};
I want my compiler to stick that in 4 bytes and move it around in
registers, of course. Now, you want to make it carry the weight
of a _vptr_ *just in case* somebody does:
class VPoint: public Point {public: virtual ~VPoint();}
and
Point *p=new VPoint;
//...
dispose(p);
where "dispose(Point *)" is a function written and compiled far
in advance of anybody dreaming up VPoint, which at the end does
"delete p;"?
In other words, can the compiler, separately compiling dispose()
into a library-resident object before anybody ever inherited
from Point, "know" that Point's dtor is nonvirtual, or does it
have to fear that it can "change from under it" unexpectedly,
and therefore must always take a vptr from somewhere inside Point?
A pointer is 8 bytes on Alpha. Do you realize your proposal
may require a 200% space overhead on this class, or doing
without separate compilation altogether?
The philosophy of C++: if somebody does not use a feature, they
must pay no price whatsoever for the mere existence of that
feature. It can't be followed 100%, but it's a good guiding
principle, and IMHO it has served the language pretty well.
Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia Fax: +39 (51) 597120
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Herb Sutter
Date: Fri, 10 Nov 1995 19:29
Date: Fri, 10 Nov 1995 19:29
53 lines
2953 bytes
2953 bytes
In article <47u94u$4of@bigboote.WPI.EDU>, parker@WPI.EDU (Chris Parker) wrote: >>>Is virtualness inherited by destructors? Does C++ automatically make all >>>applicable superclasses also have virtual destructor if they don't already? No. > May I inquire when you would ever *not* want the destructor to be virtual? Check out the FAQ under Question 75 (or thereabouts, the number may have changed slightly since my version), Cline's FAQ book under Questions 98-99, Scott Meyers' "Effective C++" (can't recall the section as I loaned the book to someone), C++PL2 pg 216, D&E concidentally also pg 216, etc. Short answer: When the class has no other virtual functions and you'll never destroy derived objects through a base pointer. (Related question: Should compilers warn you when you have a virtual function but a non-virtual dtor? Answer: Not mandated, but encouraged as a "quality of implementation" issue.) >Probably only in the leaf of the class heirarchy. Destroying the object above >the leaf child without having a virtual destructor causes nothing but a >memory leak, and quite possibly pain and hardship. That's an understatement. Two major problems besides a simple memory leak: slicing and heap corruption, both of which break program correctness and are murder to debug. >So, I propose that if that if at any point in a class >heirarchy tree a destructor is declared virtual, all destructors in the tree >are virtual because that is really what you are trying to ask for. What do >you think? No. Say I have base B and derived D1 and D2. Only D2 has a virtual dtor. Why should this imply that D1 ought to have one? Or even B for that matter, if the D2 designer is anticipating further-derived objects will be accessed through D2 pointers but knows B pointers aren't used or contemplated? (If you think this discussion is interesting, read the FAQ about 'when should operator= be virtual'.) Herb ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Herb Sutter 2228 Urwin, Ste 102 voice (416) 618-0184 Connected Object Solutions Oakville ON Canada L6L 2T2 fax (905) 847-6019 --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Bill Leonard
Date: Fri, 10 Nov 1995 20:01
Date: Fri, 10 Nov 1995 20:01
60 lines
3267 bytes
3267 bytes
In article <47u94u$4of@bigboote.WPI.EDU>, parker@WPI.EDU (Chris Parker) writes:
> May I inquire when you would ever *not* want the destructor to be virtual?
To save time and space. If there are no *other* virtual functions in the
class, then class objects need not contain a virtual function table
pointer, and access to a non-virtual destructor is faster.
The only time you *DO* need for a class to have a virtual destructor is
when you plan to delete objects of that class using a pointer or reference
to some base class. There are *many* classes for which that is not true,
especially when the classes otherwise have no virtual member functions.
> The only disadvantage of this is there is price to pay at runtime when
> freeing the object because we need to find the destructor function through
> dynamic binding. So, I propose that if that if at any point in a class
> heirarchy tree a destructor is declared virtual, all destructors in the tree
> are virtual because that is really what you are trying to ask for. What
> do you think?
This is virtually (sorry for the pun) impossible in your average C++
compilation environment. It would require the compiler to know about all
derived classes before it could generate code for any manipulation of a
given class object. Consider the following:
class A { A(); ~A(); }
A * a = Foo();
delete a; // Virtual or not?
Now if some other compilation unit somewhere is suddenly going to force A
to have a virtual destructor, the compiler must add a virtual function
table pointer to class A. Calls to class A's destructor, as in the "delete
a" above, cannot be completely compiled without global knowledge of all
classes derived from A.
Now all that is technically feasible, but is it desirable? Not in my
opinion. What problem are you solving by adding this requirement that
cannot be solved another way, say by making the destructors virtual
*explicitly* in the first place?
--
Bill Leonard
Harris Computer Systems Corporation
2101 W. Cypress Creek Road
Fort Lauderdale, FL 33309
Bill.Leonard@mail.hcsc.com
These opinions and statements are my own and do not necessarily reflect the
opinions or positions of Harris Computer Systems Corporation.
------------------------------------------------------------------------------
I feel like I've been sent for and couldn't go, and weren't needed after I
got there.
------------------------------------------------------------------------------
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: John Max Skaller
Date: Fri, 10 Nov 1995 22:37
Date: Fri, 10 Nov 1995 22:37
64 lines
2347 bytes
2347 bytes
parker@WPI.EDU (Chris Parker) wrote:
>Does C++ require you to declare your destructor virtual whenever you declare
>any other member function in the class to be virtual?
No. [The destructor will be virtual if and only if it is declared
as such OR a destructor of a direct or indirect base is declared
as such]
>Is it acceptable according to the standard
There is NO standard yet.
>for the destructor to be the only
>virtual member in the class?
Yes.
>Is virtualness inherited by destructors?
As above. (Yes :-)
>
>If virtualness of destructors is inherited, then what is supposed to happen to
>in the case where one of our subclasses uses multiple inheritance and one
>of the other trees leading to the subclass doesn't declare destructors to be
>virtual anywhere?
The derived class dtor is virtual.
What happens if you delete an object of a derived
type via a pointer to a base for which the destructor is NOT
virtual is not defined. So don't do it :-)
E.g. do NOT do:
struct Base {};
struct Derived : Base { int x; };
Base *b = new Derived;
delete b; // CRASH!!
Virtualness of the base dtor is required here to dispatch down to the
destructor of the most derived class, both to destroy the
complete object AND to deallocate the correct memory extent. Eg:
struct Base { virtual ~Base(){} };
struct Derived : Base { int x; };
Base *b = new Derived;
delete b; // OK!!
--
John Max Skaller voice: 61-2-566-2189
81 Glebe Point Rd fax: 61-2-660-0850
GLEBE NSW 2037 email: maxtal@suphys.physics.oz.au
AUSTRALIA email: skaller@maxtal.com.au
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: John Max Skaller
Date: Fri, 10 Nov 1995 22:55
Date: Fri, 10 Nov 1995 22:55
33 lines
1524 bytes
1524 bytes
martelli@cadlab.it (Alex Martelli) wrote: > >parker@WPI.EDU (Chris Parker) writes: > ... >If that subclass is destroyed through a pointer to an ancestor whose >dtor isn't virtual, undefined behaviour (violation of a "shall"). No no! Undefined behaviour is NOT a violation. Conformance applies to COMPILERS. When behaviour is not defined, the compiler can produce code that does anything, because there is no requirement to satisfy. So it's exactly the opposite of what you said: where behaviour is undefined is the one place it is IMPOSSIBLE for a "shall" to be violated, because there isn't one :-) -- John Max Skaller voice: 61-2-566-2189 81 Glebe Point Rd fax: 61-2-660-0850 GLEBE NSW 2037 email: maxtal@suphys.physics.oz.au AUSTRALIA email: skaller@maxtal.com.au --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Herb Sutter
Date: Sat, 11 Nov 1995 04:37
Date: Sat, 11 Nov 1995 04:37
25 lines
1644 bytes
1644 bytes
In article <4805l3$hst@steel.interlog.com>, I wrote: >> May I inquire when you would ever *not* want the destructor to be virtual? > >Check out the FAQ under Question 75 (or thereabouts, the number may have >changed slightly since my version), Cline's FAQ book under Questions 98-99, >Scott Meyers' "Effective C++" (can't recall the section as I loaned the book >to someone), C++PL2 pg 216, D&E concidentally also pg 216, etc. I got off my duff and fetched the latest FAQ. It's number 79 now, not 75. >Short answer: When the class has no other virtual functions and you'll never >destroy derived objects through a base pointer. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Herb Sutter 2228 Urwin, Ste 102 voice (416) 618-0184 Connected Object Solutions Oakville ON Canada L6L 2T2 fax (905) 847-6019 --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Herb Sutter
Date: Mon, 13 Nov 1995 06:50
Date: Mon, 13 Nov 1995 06:50
49 lines
2844 bytes
2844 bytes
In article <9531520.16333@mulga.cs.mu.OZ.AU>,
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
>>Is virtualness inherited by destructors? Does C++ automatically make all
>>applicable superclasses also have virtual destructor if they don't already?
>
>Yes.
No. :-) (I think he did mean "superclasses" (base classes), it wasn't a typo.
I missed this on first read too.)
[Moderator's note: oops, thanks for correcting me on that one.
The answer to the first question "Is virtualness inherited by
destructors?" is indeed "yes", but as you pointed out, the answer to
the second one is "no", since derived classes (subclasses) inherit
from base classes (superclasses), not vice versa. -fjh]
>>If virtualness of destructors is inherited, then what is supposed to happen
>>to in the case where one of our subclasses uses multiple inheritance and one
>>of the other trees leading to the subclass doesn't declare destructors to be
>>virtual anywhere?
>
>I'm not sure I understand exactly what you are asking.
>Could you be more specific (post code)?
He's talking about 'inheriting up' (making a base's dtor virtual if any
derived dtor is virtual) and so there is no answer because that's not C++.
However, it might help Chris if we answered a related question using
inheritance in the proper direction (down!):
struct Base1 { virtual ~Base1() {}; }
struct Base2 { ~Base2() {}; }
struct Derived : public Base1, public Base2 { ... };
This question is, Is Derived::~Derived() virtual, since one of the bases has a
virtual dtor and one doesn't? This answer is, Yes: 'once virtual, always
virtual' (in derived classes), just like with any virtual member function.
Herb
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Herb Sutter 2228 Urwin, Ste 102 voice (416) 618-0184
Connected Object Solutions Oakville ON Canada L6L 2T2 fax (905) 847-6019
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: Harald Fuchs
Date: Mon, 13 Nov 1995 13:08
Date: Mon, 13 Nov 1995 13:08
21 lines
1911 bytes
1911 bytes
herbs@interlog.com (Herb Sutter) writes:
> However, it might help Chris if we answered a related question using
> inheritance in the proper direction (down!):
> struct Base1 { virtual ~Base1() {}; }
> struct Base2 { ~Base2() {}; }
> struct Derived : public Base1, public Base2 { ... };
> This question is, Is Derived::~Derived() virtual, since one of the bases has
> a virtual dtor and one doesn't? This answer is, Yes: 'once virtual, always
> virtual' (in derived classes), just like with any virtual member function.
~Derived is virtual with respect to Base1, but AFAIK not with respect
to Base2. If you delete a Derived* through a Base2*, all compilers I
know only call ~Base2 ().
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors: MSVC 2.2 errors
Author: Larry West
Date: Tue, 14 Nov 1995 13:53
Date: Tue, 14 Nov 1995 13:53
113 lines
4366 bytes
4366 bytes
hf@colibri.de (Harald Fuchs) wrote in comp.std.c++:
> > struct Base1 { virtual ~Base1() {}; }
> > struct Base2 { ~Base2() {}; }
> > struct Derived : public Base1, public Base2 { ... };
>~Derived is virtual with respect to Base1, but AFAIK not with respect
>to Base2. If you delete a Derived* through a Base2*, all compilers I
>know only call ~Base2 ().
This seemed correct to me, but I wanted to check, so I compiled a sample
program [see below] under Borland C++ (16-bit EasyWin and 32-bit console
app) on Windows 95, MSVC++ 2.2 (32-bit console app) on Windows NT, and
MSVC++ 1.52 (16-bit DOS app). Borland and MSVC++ 1.52 performed as you'd
expect [here's the output]:
pB1w==pDw: ~Derived ~Base2 ~Base1
pB2x==pDx: ~Base2
pDDy==pDy: ~Derived ~Base2 ~Base1
pDz as is: ~Derived ~Base2 ~Base1
Meaning that deleting Derived through a pointer of type Base2 (with
non-virtual dtor) does in fact only call Base2, since there is in principle
no information knowable to the compiler that there may be more to the
object than just Base2.
But the news is that MSVC++ 2.2 version (a console application run on both
NT and 95) faulted on the second delete (heap error), through the base
class which has a non-virtual dtor. Source code at end.
First, a minor detour: while I was doing this, I also determined that MSVC
1.52 and 2.2 still both contain a large flaw in initialization. (v1.50 had
this, too):
class clown { };
clown bozo; // pay no attention to the programming _style_
clown &returnref()
{
return bozo;
}
void sideshowbob()
{
clown &crusty( returnref() ); // fails
clown ronald( returnref() ); // passes
}
Borland compiles this fine. MSVC 2.2 gives errors C2061 (syntax error:
identifier 'returnref') and C2530 (references must be initialized).
Disappointing. This has been in C++ for a very long time, and is pretty
clearly discussed in the ARM sections 8.4 and 8.4.3.
Anyway, here's the source code for the EasyWin, 32-bit Console app and DOS
app versions; the 32-bit Windows code is pointlessly longer, if someone
really wants it, email me.
#ifdef __BORLANDC__
# include <iostream.h>
#else
# include <ostream.h>
#endif
struct Base1 { virtual ~Base1(); };
struct Base2 { ~Base2(); };
struct Derived : public Base1, public Base2 { ~Derived(); };
Base1::~Base1()
{
cout << " ~Base1";
}
Base2::~Base2()
{
cout << " ~Base2";
}
Derived::~Derived()
{
cout << " ~Derived";
}
int main()
{
Derived *pDw = new Derived;
Derived *pDx = new Derived;
Derived *pDy = new Derived;
Derived *pDz = new Derived;
Base1 *pB1w = pDw;
Base2 *pB2x = pDx;
Derived *pDDy = pDy; // for completeness
cout << "\npB1w==pDw:";
delete pB1w;
cout << "\npB2x==pDx:";
delete pB2x; // with VC++ 2.2, faults here.
cout << "\npDDy==pDy:";
delete pDDy;
cout << "\npDz as is:";
delete pDz;
cout << "\n";
return 0;
}
----------
(c) Copyright 1995 by Larry West; I hereby grant rights to copy
my contribution within this forum or in email exchanges for purposes
of discussion, as long as attributions are maintained. Editing for
brevity is encouraged.
----------
LarryWest@msn.com (MS Exchange or UUEncoded attachments only)
lwest@ix.netcom.com (MIME, BinHex, UUEncoded attachments okay)
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
Author: John Max Skaller
Date: Sun, 19 Nov 1995 17:32
Date: Sun, 19 Nov 1995 17:32
95 lines
4506 bytes
4506 bytes
martelli@cadlab.it (Alex Martelli) wrote:
>John Max Skaller <maxtal@suphys.physics.su.oz.au> writes:
> ...
>>>If that subclass is destroyed through a pointer to an ancestor whose
>>>dtor isn't virtual, undefined behaviour (violation of a "shall").
>
>>No no! Undefined behaviour is NOT a violation.
>
>No, but if the _program_ violates a "shall", undefined behaviour
>may result.
NO. My point is that this is NOT the case (as I understand it).
A "shall" on the program is to be interpreted as a requirement
on the compiler to issue a diagnostic.
>>where behaviour is undefined is the one place
>>it is IMPOSSIBLE for a "shall" to be violated,
>>because there isn't one :-)
>
>5.3.5 verse 3 says "the static type shall have a virtual destructor or
>the behaviour is undefined";
The wording in the Working Paper is NOT CONSISTENT (yet).
This clause is misworded. It SHOULD say "..if the static type
has a virtual destructor then ... (else behaviour is undefined)."
Technically, in C++ there is NO notion of a conforming
program and the Working Paper can NOT "shall" a programmer.
Unfortunately, much of the WP was lifted from the ARM
and the style therein addresses the programmer,
(as is appropriate for a reference manual) rather
than the implementor (as is appropriate for the C++ Standard).
(ISO C addresses both, C++ quite specifically and
deliberately does NOT).
Andrew has suggested fixing this with minimal editorial
changes by _defining_ "the program shall X" to mean
"if the program is not X, it is ill formed" -- which is
a constraint on the compiler to issue a diagnostic.
It is WOULD be possible to define a "shall" on the
program to mean "behaviour is undefined" INSTEAD. However,
it CANNOT simultaneously mean "ill formed if violated"
because the two things a diametrically
opposed notions: "ill formed" programs require a diagnostic,
behaviour is completely deterministic, undefined programs
require no diagnostic, indeed, all requirements on the
implementor are waived.
>So, the undefined behaviour "is NOT a violation", but it can _follow_
>from a violation on the program's part -- therefore, it's QUITE
>possible for a "shall" to _have been_ violated (by the program)
>where behaviour is (becomes) undefined.
Only in that AFTER a diagnostic is issued for an ill
formed program, all constraints on the implementor
are waived.
When the WP says "behaviour is undefined"
(or simply fails to defined behaviour), then it
is usually being quite specific in saying the
there is NO POSSIBLE VIOLATION by the compiler:
all bets are off.
To understand this another way: given some code,
the WP _always_ defines a range of permitted
behaviours:
1. Issue a diagnostic ("Ill formed")
2. Do exactly one thing ("Deterministic")
3. Do one of several things. ("Unspecified, non-deterministic")
4. Do anything. ("undefined behaviour").
So "undefined behaviour" is just the universal set,
and specific behaviour is just a singleton set,
-- including "ill formed". Nothing is more different
than these two sets!
A compiler is conforming if and only if it produces
a behaviour in the specified set (and has appropriate
documentation of implementation defined stuff).
--
John Max Skaller voice: 61-2-566-2189
81 Glebe Point Rd fax: 61-2-660-0850
GLEBE NSW 2037 email: maxtal@suphys.physics.oz.au
AUSTRALIA email: skaller@maxtal.com.au
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads