Article View: comp.std.c++
Article #2494Re: Exceptions in destructors.
From: Scott Meyers
Date: Fri, 10 Nov 1995 19:14
Date: Fri, 10 Nov 1995 19:14
113 lines
3458 bytes
3458 bytes
>While trying to implement an exception-safe array class (and model it
>on the built-in C style arrays as closely as possible), it occured to
>me that the draft doesn't really have much to say about the case of
>exceptions thrown in destructors. Two cases occur to me:
> T a[ 5 ] ;
>
>When destructing the third element (for example), an exception is
>thrown. Are the remaining elements destructed? I would say yes.
I agree. "Stack unwinding" and "object unwinding"
(destruction) are closely related. If during destruction
an exception is thrown, destruction continues (provided
there is a reachable handler)
I'm inclined to disagree. How is destruction to continue? Suppose we
have this:
try {
T a[5];
}
catch (...) {
// do something here
}
Now suppose destruction of a[3] throws. Do we go to the handler? If
so, do we then go back into the try block to try destroying the rest of
a? What if the handler does a rethrow, and the exception is not caught for
many stack frames. After handling the exception, there is no context to
return to to continue destroying a. I don't see how this can work.
If we don't go to the handler when a[3] throws, what if a[2]'s destructor
also throws? Then we've got two active exceptions, and it's terminate
time.
thrown. As if:
delete p;
meant:
try { p->~P(); }
catch(...) {
operator delete(p);
throw;
}
operator delete(p);
[Smly for array case?]
Does this imply that for an array, you're suggesting the above code
(more or less) be put inside an implicit loop that cyles through each
member of the array? Doesn't the implicit catch(...) hijack any
client-provided exception handling?
As long as we're on the topic of exceptions in destructors, here's
another question. If a derived class destructor throws an exception, do
member and base class destructors still get called?
Consider this program:
#include <iostream.h>
class M {
public:
~M() { cout << "M destructor\n"; }
};
class B {
M m;
public:
~B() { cout << "B destructor\n"; }
};
class D: public B {
M m;
public:
~D() { cout << "Starting D destructor\n";
throw "Ouch!";
cout << "Ending D destructor\n";
}
};
int main()
{
D d;
return 0;
}
When d is destroyed, D's destructor throws. Are destructors
nevertheless called for D::m, the B part of d, and B::m? My feeling is
the answer should be no, in the same way that the remainder of D's
destructor is not executed after the throw. Different compilers do
different things, however. Who knows what is supposed to happen?
Scott
---
[ 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. ]
Technical Details
Message-ID:
<smeyersDHt9t9.2sK@netcom.com>Path:
arc1-ca.pugleaf.net!128.32.155.1!mattShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!128.32.155.1!matt From: smeyers@netcom.com (Scott Meyers) Newsgroups: comp.std.c++ Subject: Re: Exceptions in destructors. Date: 10 Nov 1995 19:14:04 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) Approved: matt@physics2.Berkeley.EDU (Matt Austern) Message-ID: <smeyersDHt9t9.2sK@netcom.com> NNTP-Posting-Host: physics2.berkeley.edu