tags:

views:

401

answers:

7

I know the rule is to NEVER throw one during a destructor, and I understand why. I would not dare do it. But even the C++ Faq Lite says that this rule is good 99% of the time. What is the other 1% that they fail to delve into?

Link to the C++ Faq Lite bullet point on throwing from ~():

+3  A: 

If everything's so knackered that you want to cause the program to terminate via the exception code flow.

Scott Langham
But... I've yet to feel the need to do this!
Scott Langham
You can't know, down in a destructor, what the rest of the system can do. I wonder what the official policy on calling exit() or _exit() from a destructor is? Or abort()? Probably not recommended - ever.
Jonathan Leffler
A: 

If the destruction is part of a controlled process, then it would be acceptable, but still, you need to get rid of remaining references as much as possible, so throwing might not be good.

Destruction can happen implicitely so often that a throw might break the normal code logic.

Vincent
+1  A: 

You would have to guarantee that the destructor is not being called, because of another exception.

That being said I don't use exceptions. But if I was compelled to use them to keep my job, I'd never throw an exception from a destructor.

Thanks, can you elaborate on why you don't use exceptions? Maybe there is another topic on this on SO? I know they are a debated feature, but curious to hear why you don't when most of the Sutter material I read says to use them.
ApplePieIsGood
See my answer below; some people avoid exceptions because you have to design your exception paths too, and that can be complicated. But they're really essential in a robust C++ program.
Charlie Martin
I don't agree that exceptions are the only way. I believe that Stroustrop, Meyers, and Spolsky all have something to say about this topic. Try-catch blocks can get so complicated, they start looking like the if-statement situations you are trying to avoid. Aborting immediately can be appropriate.
Exceptions should be used for exceptional situations, not control logic. Ramping up an exception is expensive. Often, not handling exceptions and letting the application terminate (possibly though an unhandled exception filter) is the best way to "handle" them.
Aaron
+9  A: 

Just don't do it. If the stars and planets align in such a way that you find you need to...

Still don't do it.

John Sonmez
Seems like the only reason one can come up with is still fraught with peril. I therefore concur, there is no real justifiable reason to do this.
ApplePieIsGood
+2  A: 

You can throw an exception from a destructor if this destructor is not called automatically during stack unwinding, or throwing the exception will result in a call of terminate(). To determine if it is safe to throw exceptions from a destructor, use standard function uncaught_exception(); if it returns false, it is safe to throw an exception

dmityugov
Interesting. If this function is part of the standard, and makes it that easy to figure out, I guess it would provide at least one argument for why it's OK to do this. However you still end up with behavior where two different things can happen during an exception within a destructor.
ApplePieIsGood
+10  A: 

Wow, I was about to vote Juan up until I saw the part about never using exceptions.

Okay, first of all, Juan has it correct. If, for whatever reason, you end up in that situation of two exceptions chasing one another up the stack, C++ will simply throw up its hands and its last meal and terminate abnormally. So, throwing an exception from a dtor is a guarantee that you have a possible code path that leads to an unplanned abnormal termination, which is in general a bad thing. If that's what you want, be straightforward about it, call abort or exit, and get it over with.

The part about avoiding it by not using exceptions, however, is bad advice. Exceptions are really an essential mechanism in C++ for systems that are going to be robust and run for a long time; they're really the only way to guarantee that you can handle error situations without leaking resources all over the floor.

It happens I used to work for Marshall Cline, the guy who wrote that FAQ, and taught C++ from the FAQ Book; because of that, I can tell you you're misinterpreting the answer a little. He's not saying "gee, there is this one case where it would be okay, but I'm not goin to ell you about it," he's saying "I'm sure that if I say absolutely and without exception don't throw from a dtor someone, someday, will come up with one off-the-wall example that makes sense. But I don't know of one and don't really believe it. Don't try this at home, and consult an attorney, no warranty express or implied."

Charlie Martin
Thanks for the in depth answer. I was sort of being cute by suggesting he was hiding the answer, I got his drift, but figured he had one in mind that he didn't want to encourage. Turns out he didn't, which makes his point even stronger.
ApplePieIsGood
I didn't say never to use exceptions. I said I'd never use exceptions, unless it was required in my job.Always write exception safe code. Exceptions are only one of several ways to handle errors.
That's fine, Juan, I'm just still saying you're mistaken. Exceptions, correctly used, are the best mechanism available in C++. If you refuse to use them, you're cheating yourself of an effective mechanism.
Charlie Martin
I believe I am not mistaken in saying I will never use exceptions. To be honest, I have been forced to catch exceptions in python because that is how the interface communicated problems. I will handle whatever reporting scheme a library will require. I enjoyed reading Spolsky's article on this.
+1 for the in-depth explanation.
ceretullis
Oh, I'm sure you're correct is saying you won't use exceptions. I'm just saying refusing to use exceptions is a mistake. I enjoyed his article too, but he's still wrong.
Charlie Martin
+1  A: 

I suppose if you could reliably detect a really bad situation inside a destructor, one that was so bad that there was no good way to deal with it, and you had to ensure that the process stopped NOW before something else happened.... (imagine a computer hooked up to a gun or a nuclear missile) but two other thoughts come to mind:

  1. Instead of throwing an exception it would be better to call exit() or abort() or TerminateProcess() or something that explicitly stops things, rather than assuming that you know what the compiler will turn your "throw an exception in the destructor" into when it compiles.

  2. This is more of a contrived example. Extreme safety checks should be handled in a real function that's executed on purpose at well-defined times (or better yet, handled in hardware or redundant processors) and not as an afterthought during a destructor.

Jason S
FYI, if the computer was hooked up to a gun or nuclear missile, the code would probably be written in Ada not C++.
ceretullis