Sample (non-working) code:
#incude <string>
class Foo
{
public:
// constructor
Foo () {}
// destructor
~Foo ()
{
// do something here that will throw (e.g. some logging)
// is the std::string properly destructed?
}
private:
std::string m_s;
};
thanks
Well, you should start from a very important C++ guideline which says
that destructors should not throw. Never!
If you implement a destructor that might throw you'll be unable to
rely on others well know C++ idioms. Basically, you won't be able to
write exception-safe code and provide any kind of commit-or-rollback
guarantee.
In addition, you'll also be in trouble when using operators like new[]
and delete[].
Bottom line: Don't let your destructors throw.
--
Leandro T. C. Melo
Never use the word never!
The reasoning I've heard is: When an exception is thrown from any part
of your code, the stack starts to unwind. This includes calling any
appropriate destructors. If a destructor throws an exception, then what
is supposed to happen? Does the new exception take precedence? Does the
old one trump?
The answer is: I don't care, because it is probably not what I want.
Don't let your destructor throw an exception.
Worse case scenario, let the program die immediately.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
It is well defined what happens when an exception is thrown during
stack unwinding, so there is no guessing what will happen.
I found the portion of the standard that actually *answers* my
specific question.
The relevant section is 15.2.2.
I doubt 15.2.2 is relevant, because in 99.99% an exception thrown from a
destructor will terminate the process.
Can not think of an example where 0.01% this is not true.
Of course it's relevant because it answered my specific question.
*******
15.2.2 says:
An object that is partially constructed or partially destroyed will
have destructors executed for all of its fully constructed subobjects,
that is, for subobjects for which the constructor has completed
execution and the destructor has not yet begun execution. Should a
constructor for an element of an automatic array throw an exception,
only the constructed elements of that array will be destroyed. If the
object or array was allocated in a new-expression, the matching
deallocation function (3.7.3.2, 5.3.4, 12.5), if any, is called to
free the storage occupied by the object.
******
For an exception thrown from a destructor ***during stack
unwinding***, the *default* action is to terminate the process. So
that only happens during stack unwinding - i.e. when an exception has
already been thrown.
Sorry I misunderstood you.
The answer to your question is : yes, all constructed class members will
be properly destructed.
And unless you are doing something like in the following example, your
process should be properly destructed as well :P
struct A
{
~A() { throw "hi"; }
};
int main()
{
try
{
A *a = new A;
try
{
delete(a);
}
catch(...)
{
}
}
catch(...)
{
}
}
> > It is well defined what happens when an exception is thrown
> > during stack unwinding, so there is no guessing what will
> > happen.
> > I found the portion of the standard that actually *answers*
> > my specific question.
> > The relevant section is 15.2.2.
> I doubt 15.2.2 is relevant, because in 99.99% an exception
> thrown from a destructor will terminate the process.
That's simply false. Most of the time, an exception thrown from
a destructor will NOT terminate the process.
> Can not think of an example where 0.01% this is not true.
class ThrowsInDestructor
{
public:
~ThrowsInDestructor() { throw 42; }
} ;
int
main()
{
try {
ThrowsInDestructor t ;
std::cout << "t constucted" << std::endl ;
} catch ( int i ) {
return i ;
}
return 0 ;
}
The problem isn't that most of the time, throwing from a
destructor will terminate the process. The problem is
guaranteeing that this will never be the case. Something that
is very difficult, if not impossible, for most general purpose
classes (but there exist a very few, special classes, whose sole
purpose is for the destructor to throw).
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34