RAII vs. exceptions - c++

The more we use RAII in C++, the more we find ourselves with destructors that do non-trivial deallocation. Now, deallocation (finalization, however you want to call it) can fail, in which case exceptions are really the only way to let anybody upstairs know of our deallocation problem. But then again, throwing-destructors are a bad idea because of the possibility of exceptions being thrown during stack unwinding. std::uncaught_exception() lets you know when that happens, but not much more, so aside from letting you log a message before termination there's not much you can do, unless you're willing to leave your program in an undefined state, where some stuff is deallocated/finalized and some not.
One approach is to have no-throw destructors. But in many cases that just hides a real error. Our destructor might, for example, be closing some RAII-managed DB connections as a result of some exception being thrown, and those DB connections might fail to close. This doesn't necessarily mean we're ok with the program terminating at this point. On the other hand, logging and tracing these errors isn't really a solution for every case; otherwise we would have had no need for exceptions to begin with.
With no-throw destructors we also find ourselves having to create "reset()" functions that are supposed to be called before destruction - but that just defeats the whole purpose of RAII.
Another approach is just to let the program terminate, as it's the most predictable thing you can do.
Some people suggest chaining exceptions, so that more than one error can be handled at a time. But I honestly never actually seen that done in C++ and I've no idea how to implement such a thing.
So it's either RAII or exceptions. Isn't it? I'm leaning toward no-throw destructors; mainly because it keeps things simple(r). But I really hope there's a better solution, because, as I said, the more we use RAII, the more we find ourselves using dtors that do non-trivial things.
Appendix
I'm adding links to interesting on-topic articles and discussions I've found:
Throwing Destructors
StackOverflow discussion on the problems with SEH
StackOverflow discussion on throwing-destructors (thanks, Martin York)
Joel on Exceptions
SEH Considered Harmful
CLR Exception Handling which also touches on exception chaining
Herb Sutter on std::uncaught_exception and why it's not as useful as you think
Historical discussion on the matter with interesting participants (long!)
Stroustrup explaining RAII
Andrei Alexandrescu's Scope Guard

You SHOULD NOT throw an exception out of a destructor.
Note: Updated to refeclt changes in the standard:
In C++03
If an exception is already propagating then the application will terminate.
In C++11
If the destructor is noexcept (the default) then the application will terminate.
The Following is based on C++11
If an exception escapes a noexcept function it is implementation defined if the stack is even unwound.
The Following is based on C++03
By terminate I mean stop immediately. Stack unwinding stops. No more destructors are called. All bad stuff. See the discussion here.
throwing exceptions out of a destructor
I don't follow (as in disagree with) your logic that this causes the destructor to get more complicated.
With the correct usage of smart pointers this actually makes the destructor simpler as everything now becomes automatic. Each class tides up its own little piece of the puzzle. No brain surgery or rocket science here. Another Big win for RAII.
As for the possibility of std::uncaught_exception() I point you at Herb Sutters article about why it does not work

From the original question:
Now, deallocation (finalization,
however you want to call it) can fail,
in which case exceptions are really
the only way to let anybody upstairs
know of our deallocation problem
Failure to cleanup a resource either indicates:
Programmer error, in which case, you should log the failure, followed by notifying the user or terminating the application, depending on application scenario. For example, freeing an allocation that has already been freed.
Allocator bug or design flaw. Consult the documentation. Chances are the error is probably there to help diagnose programmer errors. See item 1 above.
Otherwise unrecoverable adverse condition that can be continued.
For example, the C++ free store has a no-fail operator delete. Other APIs (such as Win32) provide error codes, but will only fail due to programmer error or hardware fault, with errors indicating conditions like heap corruption, or double free, etc.
As for unrecoverable adverse conditions, take the DB connection. If closing the connection failed because the connection was dropped -- cool, you're done. Don't throw! A dropped connection (should) result in a closed connection, so there's no need to do anything else. If anything, log a trace message to help diagnose usage issues. Example:
class DBCon{
public:
DBCon() {
handle = fooOpenDBConnection();
}
~DBCon() {
int err = fooCloseDBConnection();
if(err){
if(err == E_fooConnectionDropped){
// do nothing. must have timed out
} else if(fooIsCriticalError(err)){
// critical errors aren't recoverable. log, save
// restart information, and die
std::clog << "critical DB error: " << err << "\n";
save_recovery_information();
std::terminate();
} else {
// log, in case we need to gather this info in the future,
// but continue normally.
std::clog << "non-critical DB error: " << err << "\n";
}
}
// done!
}
};
None of these conditions justify attempting a second kind of unwind. Either the program can continue normally (including exception unwind, if unwind is in progress), or it dies here and now.
Edit-Add
If you really want to be able to keep some sort of link to those DB connections that can't close -- perhaps they failed to close due to intermittent conditions, and you'd like to retry later -- then you can always defer cleanup:
vector<DBHandle> to_be_closed_later; // startup reserves space
DBCon::~DBCon(){
int err = fooCloseDBConnection();
if(err){
..
else if( fooIsRetryableError(err) ){
try{
to_be_closed.push_back(handle);
} catch (const bad_alloc&){
std::clog << "could not close connection, err " << err << "\n"
}
}
}
}
Very not pretty, but it might get the job done for you.

You're looking at two things:
RAII, which guarantees that resources are cleaned up when scope is exited.
Completing an operation and finding out whether it succeeded or not.
RAII promises that it will complete the operation (free memory, close the file having attempted to flush it, end a transaction having attempted to commit it). But because it happens automatically, without the programmer having to do anything, it doesn't tell the programmer whether those operations it "attempted" succeeded or not.
Exceptions are one way to report that something failed, but as you say, there's a limitation of the C++ language that means they aren't suitable to do that from a destructor[*]. Return values are another way, but it's even more obvious that destructors can't use those either.
So, if you want to know whether your data was written to disk, you can't use RAII for that. It does not "defeat the whole purpose of RAII", since RAII will still try to write it, and it will still release the resources associated with the file handle (DB transaction, whatever). It does limit what RAII can do -- it won't tell you whether the data was written or not, so for that you need a close() function that can return a value and/or throw an exception.
[*] It's quite a natural limitation too, present in other languages. If you think RAII destructors should throw exceptions to say "something has gone wrong!", then something has to happen when there's already an exception in flight, that is "something else has gone wrong even before that!". Languages that I know that use exceptions don't permit two exceptions in flight at once - the language and syntax simply don't allow for it. If RAII is to do what you want, then exceptions themselves need to be redefined so that it makes sense for one thread to have more than one thing going wrong at a time, and for two exceptions to propagate outward and two handlers to be called, one to handle each.
Other languages allow the second exception to obscure the first, for example if a finally block throws in Java. C++ pretty much says that the second one must be suppressed, otherwise terminate is called (suppressing both, in a sense). In neither case are the higher stack levels informed of both faults. What is a bit unfortunate is that in C++ you can't reliably tell whether one more exception is one too many (uncaught_exception doesn't tell you that, it tells you something different), so you can't even throw in the case where there isn't already an exception in flight. But even if you could do it in that case, you'd still be stuffed in the case where one more is one too many.

It reminds me a question from a colleague when I explained him the exception/RAII concepts: "Hey, what exception can I throw if the computer's switched off?"
Anyway, I agree with Martin York's answer RAII vs. exceptions
What's the deal with Exceptions and Destructors?
A lot of C++ features depend on non-throwing destructors.
In fact, the whole concept of RAII and its cooperation with code branching (returns, throws, etc.) is based on the fact deallocation won't fail. In the same way some functions are not supposed to fail (like std::swap) when you want to offer high exception guarantees to your objects.
Not that it doesn't mean you can't throw exceptions through destructors. Just that the language won't even try to support this behaviour.
What would happen if it was authorized?
Just for the fun, I tried to imagine it...
In the case your destructor fails to free your resource, what will you do? Your object is probably half destructed, what would you do from an "outside" catch with that info? Try again? (if yes, then why not trying again from within the destructor?...)
That is, if you could access your half-destructed object it anyway: What if your object is on the stack (which is the basic way RAII works)? How can you access an object outside its scope?
Sending the resource inside the exception?
Your only hope would be to send the "handle" of the resource inside the exception and hoping code in the catch, well... try again to deallocate it (see above)?
Now, imagine something funny:
void doSomething()
{
try
{
MyResource A, B, C, D, E ;
// do something with A, B, C, D and E
// Now we quit the scope...
// destruction of E, then D, then C, then B and then A
}
catch(const MyResourceException & e)
{
// Do something with the exception...
}
}
Now, let's imagine for some reason the destructor of D fails to deallocate the resource. You coded it to send an exception, that will be caught by the catch. Everything goes well: You can handle the failure the way you want (how you will in a constructive way still eludes me, but then, it is not the problem now).
But...
Sending the MULTIPLE resources inside the MULTIPLE exceptions?
Now, if ~D can fail, then ~C can, too. as well as ~B and ~A.
With this simple example, you have 4 destructors which failed at the "same moment" (quitting the scope). What you need is not not a catch with one exception, but a catch with an array of exceptions (let's hope the code generated for this does not... er... throw).
catch(const std::vector<MyResourceException> & e)
{
// Do something with the vector of exceptions...
// Let's hope if was not caused by an out-of-memory problem
}
Let's get retarted (I like this music...): Each exception thrown is a different one (because the cause is different: Remember that in C++, exceptions need not derive from std::exception). Now, you need to simultaneously handle four exceptions. How could you write catch clauses handling the four exceptions by their types, and by the order they were thrown?
And what if you have multiple exceptions of the same type, thrown by multiple failed deallocation? And what if when allocating the memory of the exception arrays of arrays, your program goes out of memory and, er... throw an out of memory exception?
Are you sure you want to spend time on this kind of problem instead of spending it figuring why the deallocation failed or how to react to it in another way?
Apprently, the C++ designers did not see a viable solution, and just cut their losses there.
The problem is not RAII vs Exceptions...
No, the problem is that sometimes, things can fail so much that nothing can be done.
RAII works well with Exceptions, as long as some conditions are met. Among them: The destructors won't throw. What you are seeing as an opposition is just a corner case of a single pattern combining two "names": Exception and RAII
In the case a problem happens in the destructor, we must accept defeat, and salvage what can be salvaged: "The DB connection failed to be deallocated? Sorry. Let's at least avoid this memory leak and close this File."
While the exception pattern is (supposed to be) the main error handling in C++, it is not the only one. You should handle exceptional (pun intended) cases when C++ exceptions are not a solution, by using other error/log mechanisms.
Because you just met a wall in the language, a wall no other language that I know of or heard of went through correctly without bringing down the house (C# attempt was worthy one, while Java's one is still a joke that hurts me on the side... I won't even speak about scripting languages who will fail on the same problem in the same silent way).
But in the end, no matter how much code you'll write, you won't be protected by the user switching the computer off.
The best you can do, you already wrote it. My own preference goes with a throwing finalize method, a non-throwing destructor cleaning resources not finalized manually, and the log/messagebox (if possible) to alert about the failure in the destructor.
Perhaps you're not putting up the right duel. Instead of "RAII vs. Exception", it should be "Trying to freeing resources vs. Resources that absolutely don't want to be freed, even when threatened by destruction"
:-)

One thing I would ask is, ignoring the question of termination and so on, what do you think an appropriate response is if your program can't close its DB connection, either due to normal destruction or exceptional destruction.
You seem to rule out "merely logging" and are disinclined to terminate, so what do you think is the best thing to do?
I think if we had an answer to that question then we would have a better idea of how to proceed.
No strategy seems particularly obvious to me; apart from anything else, I don't really know what it means for closing a database connection to throw. What is the state of the connection if close() throws? Is it closed, still open, or indeterminate? And if it's indeterminate, is there any way for the program to revert to a known state?
A destructor failing means that there was no way to undo the creation of an object; the only way to return the program to a known (safe) state is to tear down the entire process and start over.

What are the reasons why your destruction might fail? Why not look to handling those before actually destructing?
For example, closing a database connection may be because:
Transaction in progress. (Check std::uncaught_exception() - if true, rollback, else commit - these are the most likely desired actions unless you have a policy that says otherwise, before actually closing the connection.)
Connection is dropped. (Detect and ignore. The server will rollback automatically.)
Other DB error. (Log it so we can investigate and possibly handle appropriately in the future. Which may be to detect and ignore. In the meantime, try rollback and disconnect again and ignore all errors.)
If I understand RAII properly (which I might not), the whole point is its scope. So it's not like you WANT transactions lasting longer than the object anyway. It seems reasonable to me, then, that you want to ensure closure as best you can. RAII doesn't make this unique - even without objects at all (say in C), you still would try to catch all error conditions and deal with them as best as you can (which is sometimes to ignore them). All RAII does is force you to put all that code in a single place, no matter how many functions are using that resource type.

You can tell whether there is currently an exception in flight (e.g. we are between the throw and catch block performing stack unwinding, perhaps copying exception objects, or similar) by checking
bool std::uncaught_exception()
If it returns true, throwing at this point will terminate the program, If not, it's safe to throw (or at least as safe as it ever is). This is discussed in Section 15.2 and 15.5.3 of ISO 14882 (C++ standard).
This doesn't answer the question of what to do when you hit an error while cleaning up an exception, but there really aren't any good answers to that. But it does let you distinguish between normal exit and exceptional exit if you wait to do something different (like log&ignore it) in the latter case, rather than simply panicing.

If one really needs to deal with some errors during the finalization process, it should not be done within the destructor. Instead, a separate function that returns an error code or may throw should be used instead. To reuse the code, you can call this function inside the destructor, but you must not allow the exception to leak out.
As some people mentioned, it is not really resource deallocation, but something like resource commit during exit. As other people mentioned, what can you do if saving fails during a forced power-off? There are probably no all-satisfying answers, but I would suggest one of the following approaches:
Just allow the failure and loss to happen
Save the unsaved part to somewhere else and allow the recovery to happen later (see the other approach if this does not work either)
If you do not like either of this approaches, make your user explicitly save. Tell them not to rely on the auto-save during a power-off.

Related

When do I need to use throw and return?

I saw a function that uses throw to return something.
I've made some research before asking this, here, about throw and I did not find very much.
If someone could explain me when to use throw to return something and when to use the normal return statement, that would be awesome.
Using throw to return a result can be useful in a deeply nested recursion. Instead of backing out of each call level you get right back up to the top level call for this goal. I think in most other situations it's both too inefficient (because exceptions are optimized for failure handling) and too unconventional to even consider.
return is the easiest and in many situations also the most efficient way to return a computed value, a reference to a class member, a state information (e.g. an enum value), a trivial success/failure information, and, and, and. So this is the most common and usual way to evaluate function values.
throw on the other hand (like Alf already answered) deals with exception's - which, as the name already pretty clearly states :) an exception of the normal control flow: "Something very important (often something bad) happened, which requires an instant handling, I can not continue my usual processing flow and have to throw an exception immediately.". The reason can sometimes be a catastrophic and unrecoverable state in the program, but by no means always. For example, a socket losing its connection is pretty common and not a catastrophy - but can be a reason for throwing an exception nevertheless, because the socket code may be not able to continue computing.
Exceptions are usually a bit more difficult to handle - and to integrate into your program design - than usual return values, and they are - as others already stated - less efficient than simple return values, but they have a lot of benefits.
They can be caught from anywhere in the stack of calling functions
Let's say you write a game, with a game engine (e.g. Ogre), and this engine uses a direct X interface. Now something deep, deep in the DirectX interface happens, which hinders the engine from working correctly.
The error handling of this function (may be 8-10 calls deep in the call stack), which can not work properly anymore, would be nearly impossible if it would be done with normal return values - both for the engine programmers and for the game programmer. So in that case, without exceptions, the method of choice would be a non-standardized error handler - pretty similar to an exception, but not with the powerful possibilities of exceptions. Here's a practical example on how to handle this error with an exception (please ignore the real purpose of the functions, it's just to show the principle:
try
{
mHOQList[mCurrentFrame]->endOcclusionQuery();
} catch( Ogre::Exception& e )
{
if( e.getNumber() == Exception::ERR_RENDERINGAPI_ERROR
&& stdEx::string(e.getDescription()).beginsWith( "End occlusion called" ))
{
// a device lost occurred during our occlusion query. Simply ignore it.
return true;
}
else
throw;
}
We are doing an occlusion query here, which we know can not continue when a "device lost" event happens during it's operation. So we place it in a try/catch clause. When everything works out good in the endOcclusionQuery(), the catch() is never called, and everything is fine.
If an exception is thrown, we first check if we can handle it. We check the number of the exception and its description. If these informations have a specific value, we know that it's a benign error, we can safely ignore it and carry on the next frame. If we don't know how to handle it, we simply throw;, which leaves the handling of the exceplion to a catch() lower in the call hierarchy, which brings me to the next points:
They can be evaluated selectively.
The example above will catch and handle exceptions of the type Ogre::Exception, but nothing else. A std::exception or another exception type is not caught. Let's say for example the endOcclusionQuery() calls a callback in our own code, which then also gets into an exceptional state and throws. We would let this exception pass by and leave it to the lower (or higher) levels of the call hierarchy to handle it.
They can be rethrown.
In the example, we use throw; to re-throw and pass the handling to lower levels in the call hierarchy.
They can be stored and even re-thrown in a separate thread
Imagine a library with hundreds of worker threads, and a manager thread which coordinates these threads. Since exceptions are bound to a single thread, so the manager thread can never catch exceptions from the worker threads. But the worker threads can catch their own exceptions and either handle them if possible or store them, pass them to the manager thread, where it can be rethrown and be handled by the manager thread.
They can be thrown in Constructors
Constructors have no return value, and so it is impossible to check its success with return values. State members are possible, but awkward - they tend to be overlooked. So the preferrable way to deal with errors in a constructor is to throw (of course as a documented behavior). See also Throwing exceptions from constructors
They are standardized
Well when it comes to this, the example above is not the best. Ogre is a pretty old engine, long before C++11, and so the exception classes are proprietary. You can throw anything - from a char to a class LiverSausage. But today this shouldn't be done anymore - std::exception is the class of choice. It contains everything which is needed for a simple exception, and can be inherited for more sophisticated exceptions. It is commonly used and inherited in the STL, and there are helpers classes and functions like std::exception_ptr, std::current_exception() etc.
They can be used as a safe bailout for an unrecoverable program error. At the end, something ugly like this unfortunately can happen in the best programs. You can throw this fatal exception anywhere in your program, and you can catch this exception at a single place, where you can log the error, evaluate where it came from, perhaps even write a dump - so you have at least a clue what could have happened, which is at least less worse than simply crashing ;)
throw isn't used to return any value , it is used to throw exceptions i.e. if you think that a certain condition in the program is going to cause a runtime error or malfunction then you throw a exception which helps to avoid and deal with such runtime errors. Return is used to return from a function and a value to the calling function.
While this might sound bad, I actually let performance be a strong factor in guiding this decision. Most modern optimizers implement what's called zero-cost exception-handling, which ultimately translates to something like, "branch-free normal execution paths, but expensive exceptional paths".
It makes throwing quite expensive in exchange for making your normal execution paths really cheap. I don't have precise numbers for the costs but it's probably relatively extremely expensive if you're using a try/catch block just to test if a key exists in a data structure, e.g.
The other guiding force that I've found useful is the idea of an external exception outside of the programmer's control. Examples of that might be a client failing to connect to a server which should be up after repeated attempts, encountering a corrupt file, failing to allocate memory, things of this sort.
I did get into a debate one time with a colleague about whether a user jamming an abort button on a progress bar qualifies as an exceptional circumstance. I really thought it did because the operation is normally supposed to succeed, and a user aborting is a truly exceptional circumstance outside of the developer's control. On top of that it really simplified the code quite a bit over trying to propagate an abort status down the entire call stack.
In these cases where people might not agree about what is and isn't exceptional control flow, I use performance as like the deciding factor. Here throwing to abort an expensive operation isn't a big performance overhead, since it's not like we're throwing a million times in a critical loop. We're just throwing one time to abort a very expensive operation, and there the overhead of throwing becomes quite trivialized. So that's what I mean when I talk about performance being a deciding factor.

Catching exceptions in destructors

Is it possible to make a destructor catch exceptions and then re-throw them?
If so, how would I do that, since there isn't a clear place for a try statement?
Basically, I want to ideally do:
CMyObject::~CMyObject()
{
catch(...) // Catch without a try. Possible?
{
LogSomeInfo();
throw; // re-throw the same exception
}
// Normal Destructor operations
}
Background
I have a large, complex application that is throwing an unhandled exception somewhere.
I don't have easy access to main or the top level message-pump or anything similar, so there's no easy place to catch all unhandled exceptions.
I figure any unhandled exception has to pass through a bunch of destructors as the stack is unwound. So, I'm contemplating scattering a bunch of catch statements in destructors. Then at least I'd know what objects are in play when the exception is thrown. But I have no idea if this is possible, or advisable.
EDIT: You can use std::uncaught_exception to check if an exception is currently being thrown (i.e. if stack unwinding is in progress due to an exception). It is not possible to catch that exception or otherwise get access to it from your destructor. So if your logging doesn't need access to the exception itself, you can use
CMyObject::~CMyObject()
{
if(std::uncaught_exception()) {
LogSomeInfo(); // No access to exception.
}
// Normal Destructor operations
}
Note that this question was asked in 2013, meanwhile std::uncaught_exception was replaced with std::uncaught_exceptions (notice the additional s at the end) which returns an int. For a rationale, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf, so if you are using C++17, you should prefer the new version. The above paper also explains why the old std::uncaught_exception will not work as expected in some situations.
Another option might be std::set_terminate. This is useful if you want to have a method called when an exception is not caught and about to terminate the program. In the terminate handler, I usually print some information about the exception and a (demangled) backtrace of where it originates from to my log file before finally terminating the program. This is compiler and system specific, but a real helper as it saves a lot of time if you write server processes and often the log file is all you get from ops.
You can use std::uncaught_exception() which returns true if and only if there is an exception being processed. It has been available since C++98, and is superseded by std::current_exception which returns a std::exception_ptr.
However you must be careful not to throw another exception in an unguarded context, otherwise std::terminate will be caught. Example:
X::~X() {
if (std::uncaught_exception()) {
try {
LogSomeInfo();
// and do something else...
} catch(...) {}
}
}
A destructor cannot catch the exception that is causing the destruction of the instance.
You can only know if there is any "active exception" (see uncaught_exception) during the destruction (or, in C++17, how many of them there are there with uncaught_exceptions) but it's possible that the exception(s) are indeed going to be handled after that.
Dealing with exceptions is very hard, much harder than someone may think at a first sight and the reason is that exception safety doesn't scale by composition. This in my opinion means that is basically impossible to have non trivial stateful subsystems with strong exception safety (in case of an exception being thrown nothing happened to the internal state). This was discovered long ago (see 1994 Tom Cargill's "Exception handling: A False Sense of Security") but apparently is still ignored by large part of the C++ community.
The only reasonable way to handle exceptions I can think to is to have subsystems with clear well defined interfaces with thick "walls" (no side effect happening inside may escape), and that can be re-initialized to a well known state from scratch if needed when something goes wrong. This not trivial but can be done correctly to a reasonable extent.
In all other cases the global state of the system when an exception is caught is indefinite at best at the point of catch and there are in my opinion few use cases in which you can do anything in such a condition except dying immediately as loudly as possible instead of taking further actions without indeed knowing what is going on (dead programs tell no lie). Even keeping on calling destructors is somewhat questionable in my opinion.
Or you may try to be as functional as possible, but that's not an easy path either (at least for my brain) and it's also moving far away from reality (most computers are mutable objects with many billions of bits of mutable state: you can pretend this is not the case and they're instead mathematical functions with no state and with predictable output dependent on input... but in my opinion you're just deluding yourself).

Exceptions in C++ destructors if there is no uncaught_exception

People have argued pretty strongly against throwing exceptions from destructors. Take this answer as an example. I wonder whether std::uncaught_exception() can be used to portably detect whether we are in the process of unwinding the stack due to some other exception.
I find myself deliberately throwing exceptions in destructors. To mention two possible use cases:
Some resource cleanup which involves flushing buffers, so that failure likely signifies truncated output.
Destruction of an object holding a std::exception_ptr which might contain an exception encountered in a different thread.
Simply ignoring these exceptional situations feels plain wrong. And chances are that by throwing an exception some exception handler might be able to provide more useful context information than if the destructor itself were writing to std::cerr. Furthermore, throwing exceptions for all failed assertions is an important part of my unit testing approach. An error message followed by an ignored error condition wouldn't work in that case.
So my question is, is it OK to throw exceptions except when another exception is being processed, or is there a reason not to do that?
To put this in code:
Foo::~Foo() {
bool success = trySomeCleanupOperation();
if (!success) {
if (std::uncaught_exception())
std::cerr << "Error in destructor: " << errorCode << std::endl;
else
throw FooOperationFailed("Error in destructor", errorCode);
}
}
As far as I can tell, this should be safe and in many cases better than not throwing an exception at all. But I'd like to verify that.
Herb Sutter has written on the subject: http://www.gotw.ca/gotw/047.htm
His conclusion is to never throw from a destructor, always report the error using the mechanism that you would use in the case where you can't throw.
The two reasons are:
it doesn't always work. Sometimes uncaught_exception returns true and yet it is safe to throw.
it's bad design to have the same error reported in two different ways, both of which the user will have to account for if they want to know about the error.
Note that for any given reusable piece of code, there is no way to know for sure that it will never be called during stack unwinding. Whatever your code does, you can't be certain that some user of it won't want to call it from a destructor with a try/catch in place to handle its exceptions. Therefore, you can't rely on uncaught_exception always returning true if it's safe to throw, except maybe by documenting the function, "must not be called from destructors". If you resorted to that then all callers would also have to document their functions, "must not be called from destructors" and you have an even more annoying restriction.
Aside from anything else, the nothrow guarantee is valuable to users - it helps them write exception-safe code if they know that a particular thing that they do won't throw.
One way out is to give your class a member function close that calls trySomeCleanupOperation and throws if it fails. Then the destructor calls trySomeCleanupOperation and logs or suppresses the error, but doesn't throw. Then users can call close if they want to know whether their operation succeeds or not, and just let the destructor handle it if they don't care (including the case where the destructor is called as part of stack unwinding, because an exception was thrown before getting to the user's call to close). "Aha!", you say, "but that defeats the purpose of RAII because the user has to remember to call close!". Yes, a bit, but what's in question isn't whether RAII can do everything you want. It can't. What's in question is whether it consistently does less than you'd like (you'd like it to throw an exception if trySomeCleanupOperator fails), or does less surprisingly when used during stack unwinding.
Furthermore, throwing exceptions for all failed assertions is an important part of my unit testing approach
That's probably a mistake - your unit testing framework should be capable of treating a terminate() as a test failure. Suppose that an assert fails during stack unwinding - surely you want to record that, but you can't do so by throwing an exception, so you've painted yourself into a corner. If your assertions terminate then you can detect them as terminations.
Unfortunately if you terminate then you can't run the rest of the tests (at least, not in that process). But if an assertion fails then generally speaking your program is in an unknown and potentially unsafe state. So once you've failed an assertion you can't rely on doing anything else in that process anyway. You could consider designing your test framework to use more than one process, or just accept that a sufficiently severe test failure will prevent the rest of the tests running. Externally to the test framework, you can consider that your test run has three possible outcomes "all passed, something failed, tests crashed". If the test run fails to complete then you don't treat it as a pass.
This is what standard says about dtors and exceptions:
15.2
(...)
The process of calling destructors for automatic objects constructed on the path from a try block to the
point where an exception is thrown is called “stack unwinding.” If a destructor called during stack unwinding
exits with an exception, std::terminate is called (15.5.1). [ Note: So destructors should generally catch
exceptions and not let them propagate out of the destructor. —end note ]
Since you asked very ambiguous question, the answer depends:
Can you throw an exception in dtor such that application won't crash? Yes, you can (in terms: it will compile and sometimes it will run correctly).
Should you throw an exception in dtor? No, you should not, because it may (and usually it will) cause you problems.
I'd say, that a need for throwing an exception from dtor is a sign of bad design. It seems, that you're doing something in your destructor, that should be done elsewhere.

Why should exceptions be used conservatively?

I often see/hear people say that exceptions should only be used rarely, but never explain why. While that may be true, rationale is normally a glib: "it's called an exception for a reason" which, to me, seems to be the sort of explanation that should never be accepted by a respectable programmer/engineer.
There is a range of problems that an exception can be used to solve. Why is it unwise to use them for control flow? What is the philosophy behind being exceptionally conservative with how they are used? Semantics? Performance? Complexity? Aesthetics? Convention?
I've seen some analysis on performance before, but at a level that would be relevant to some systems and irrelevant to others.
Again, I don't necessarily disagree that they should be saved for special circumstances, but I'm wondering what the consensus rationale is (if such a thing exists).
The primary point of friction is semantics. Many developers abuse exceptions and throw them at every opportunity. The idea is to use exception for somewhat exceptional situation. For example, wrong user input does not count as an exception because you expect this to happen and ready for that. But if you tried to create a file and there was not enough space on disk, then yes, this is a definite exception.
One other issue is that exceptions are often thrown and swallowed. Developers use this technique to simply "silence" the program and let it run as long as possible until completely collapsing. This is very wrong. If you don't process exceptions, if you don't react appropriately by freeing some resources, if you don't log the exception occurrence or at least not notify the user, then you're not using exception for what they are meant.
Answering directly your question. Exceptions should rarely be used because exceptional situations are rare and exceptions are expensive.
Rare, because you don't expect your program crash at every button press or at every malformed user input. Say, database may suddenly not be accessible, there may not be enough space on disk, some third party service you depend on is offline, this all can happen, but quite rarely, these would be clear exceptional cases.
Expensive, because throwing an exception will interrupt the normal program flow. The runtime will unwind the stack until it finds an appropriate exception handler that can handle the exception. It will also gather the call information all along the way to be passed to the exception object the handler will receive. It all has costs.
This is not to say that there can be no exception to using exceptions (smile). Sometimes it can simplify the code structure if you throw an exception instead of forwarding return codes via many layers. As a simple rule, if you expect some method to be called often and discover some "exceptional" situation half the time then it is better to find another solution. If however you expect normal flow of operation most of the time while this "exceptional" situation can only emerge in some rare circumstances, then it is just fine to throw an exception.
#Comments: Exception can definitely be used in some less-exceptional situations if that could make your code simpler and easier. This option is open but I'd say it comes quite rare in practice.
Why is it unwise to use them for control flow?
Because exceptions disrupt normal "control flow". You raise an exception and normal execution of the program is abandoned potentially leaving objects in inconsistent state and some open resources unfreed. Sure, C# has the using statement which will make sure the object will be disposed even if an exception is thrown from the using body. But let us abstract for the moment from the language. Suppose the framework won't dispose objects for you. You do it manually. You have some system for how to request and free resources and memory. You have agreement system-wide who is responsible for freeing objects and resources in what situations. You have rules how to deal with external libraries. It works great if the program follows the normal operation flow. But suddenly in the middle of execution you throw an exception. Half of the resources are left unfreed. Half have not been requested yet. If the operation was meant to be transactional now it is broken. Your rules for handling resources will not work because those code parts responsible for freeing resources simply won't execute. If anybody else wanted to use those resources they may find them in inconsistent state and crash as well because they could not predict this particular situation.
Say, you wanted a method M() call method N() to do some work and arrange for some resource then return it back to M() which will use it and then dispose it. Fine. Now something goes wrong in N() and it throws an exception you didn't expect in M() so the exception bubbles to the top until it maybe gets caught in some method C() which will have no idea what was happening deep down in N() and whether and how to free some resources.
With throwing exceptions you create a way to bring your program into many new unpredictable intermediate states which are hard to prognose, understand and deal with. It's somewhat similar to using GOTO. It is very hard to design a program that can randomly jump its execution from one location to the other. It will also be hard to maintain and debug it. When the program grows in complexity, you just going to lose an overview of what when and where is happening less to fix it.
While "throw exceptions in exceptional cirumstances" is the glib answer, you can actually define what those circumstances are: when preconditions are satisfied, but postconditions cannot be satisfied. This allows you to write stricter, tighter, and more useful postconditions without sacrificing error-handling; otherwise, without exceptions, you have to change the postcondition to allow for every possible error state.
Preconditions must be true before calling a function.
Postcondition is what the function guarantees after it returns.
Exception safety states how exceptions affect the internal consistency of a function or data structure, and often deal with behavior passed in from outside (e.g. functor, ctor of a template parameter, etc.).
Constructors
There's very little you can say about every constructor for every class that could possibly be written in C++, but there are a few things. Chief among them is that constructed objects (i.e. for which the constructor succeeded by returning) will be destructed. You cannot modify this postcondition because the language assumes it is true, and will call destructors automatically. (Technically you can accept the possibility of undefined behavior for which the language makes no guarantees about anything, but that is probably better covered elsewhere.)
The only alternative to throwing an exception when a constructor cannot succeed is to modify the basic definition of the class (the "class invariant") to allow valid "null" or zombie states and thus allow the constructor to "succeed" by constructing a zombie.
Zombie example
An example of this zombie modification is std::ifstream, and you must always check its state before you can use it. Because std::string, for example, doesn't, you are always guaranteed that you can use it immediately after construction. Imagine if you had to write code such as this example, and if you forgot to check for the zombie state, you'd either silently get incorrect results or corrupt other parts of your program:
string s = "abc";
if (s.memory_allocation_succeeded()) {
do_something_with(s); // etc.
}
Even naming that method is a good example of how you must modify the class' invariant and interface for a situation string can neither predict nor handle itself.
Validating input example
Let's address a common example: validating user input. Just because we want to allow for failed input doesn't mean the parsing function needs to include that in its postcondition. It does mean our handler needs to check if the parser fails, however.
// boost::lexical_cast<int>() is the parsing function here
void show_square() {
using namespace std;
assert(cin); // precondition for show_square()
cout << "Enter a number: ";
string line;
if (!getline(cin, line)) { // EOF on cin
// error handling omitted, that EOF will not be reached is considered
// part of the precondition for this function for the sake of example
//
// note: the below Python version throws an EOFError from raw_input
// in this case, and handling this situation is the only difference
// between the two
}
int n;
try {
n = boost::lexical_cast<int>(line);
// lexical_cast returns an int
// if line == "abc", it obviously cannot meet that postcondition
}
catch (boost::bad_lexical_cast&) {
cout << "I can't do that, Dave.\n";
return;
}
cout << n * n << '\n';
}
Unfortunately, this shows two examples of how C++'s scoping requires you to break RAII/SBRM. An example in Python which doesn't have that problem and shows something I wish C++ had – try-else:
# int() is the parsing "function" here
def show_square():
line = raw_input("Enter a number: ") # same precondition as above
# however, here raw_input will throw an exception instead of us
# using assert
try:
n = int(line)
except ValueError:
print "I can't do that, Dave."
else:
print n * n
Preconditions
Preconditions don't strictly have to be checked – violating one always indicates a logic failure, and they are the caller's responsibility – but if you do check them, then throwing an exception is appropriate. (In some cases it's more appropriate to return garbage or crash the program; though those actions can be horribly wrong in other contexts. How to best handle undefined behavior is another topic.)
In particular, contrast the std::logic_error and std::runtime_error branches of the stdlib exception hierarchy. The former is often used for precondition violations, while the latter is more suited for postcondition violations.
Expensive kernel calls (or other system API invocations) to manage kernel (system) signal interfaces
Hard to analyze Many of the problems of the goto statement apply to exceptions. They jump over potentially large amounts of code often in multiple routines and source files. This is not always apparent from reading the intermediate source code. (It is in Java.)
Not always anticipated by intermediate code The code that gets jumped over may or may not have been written with the possibility of an exception exit in mind. If originally so written, it may not have been maintained with that in mind. Think: memory leaks, file descriptor leaks, socket leaks, who knows?
Maintenance complications
It's harder to maintain code that jumps around processing exceptions.
Throwing an exception is, to some extent, similar to a goto statement. Do that for flow control, and you end with incomprehensible spaghetti code. Even worse, in some cases you do not even know where exactly the jump goes to (i.e. if you are not catching the exception in the given context). This blatantly violates the "least surprise" principle that enhances maintainability.
Exceptions make it harder to reason about the state of your program. In C++ for instance, you have to do extra thinking to ensure your functions are strongly exception safe, than you would have to do if they didn't need to be.
The reason is that without exceptions, a function call can either return, or it can terminate the program first. With exceptions, a function call can either return, or it can terminate the program, or it can jump to a catch block somewhere. So you can no longer follow the flow of control just by looking at the code in front of you. You need to know if the functions called can throw. You may need to know what can be thrown and where it's caught, depending on whether you care where control goes, or only care that it leaves the current scope.
For this reason, people say "don't use exceptions unless the situation is really exceptional". When you get down to it, "really exceptional" means "some situation has occurred where the benefits of handling it with an error return value are outweighed by the costs". So yes, this is something of an empty statement, although once you have some instincts for "really exceptional", it becomes a good rule of thumb. When people talk about flow control, they mean that the ability to reason locally (without reference to catch blocks) is a benefit of return values.
Java has a wider definition of "really exceptional" than C++. C++ programmers are more likely to want to look at the return value of a function than Java programmers, so in Java "really exceptional" might mean "I can't return a non-null object as the result of this function". In C++, it's more likely to mean "I very much doubt my caller can continue". So a Java stream throws if it can't read a file, whereas a C++ stream (by default) returns a value indicating error. In all cases, though, it is a matter of what code you are willing to force your caller to have to write. So it is indeed a matter of coding style: you have to reach a consensus what your code should look like, and how much "error-checking" code you want to write against how much "exception-safety" reasoning you want to do.
The broad consensus across all languages seems to be that this is best done in terms of how recoverable the error is likely to be (since unrecoverable errors result in no code with exceptions, but still need a check-and-return-your-own-error in code which uses error returns). So people come to expect "this function I call throws an exception" to mean "I can't continue", not just "it can't continue". That's not inherent in exceptions, it's just a custom, but like any good programming practice, it's a custom advocated by smart people who've tried it the other way and not enjoyed the results. I too have had bad experiences throwing too many exceptions. So personally, I do think in terms of "really exceptional", unless something about the situation makes an exception particularly attractive.
Btw, quite aside from reasoning about the state of your code, there are also performance implications. Exceptions are usually cheap now, in languages where you're entitled to care about performance. They can be faster than multiple levels of "oh, the result's an error, I'd best exit myself with an error too, then". In the bad old days, there were real fears that throwing an exception, catching it, and carrying on with the next thing, would make what you're doing so slow as to be useless. So in that case, "really exceptional" means, "the situation is so bad that horrific performance no longer matters". That's no longer the case (although an exception in a tight loop is still noticeable) and hopefully indicates why the definition of "really exceptional" needs to be flexible.
There really is no consensus. The whole issue is somewhat subjective, because the "appropriateness" of throwing an exception is often suggested by existing practices within the standard library of the language itself. The C++ standard library throws exceptions a lot less frequently than say, the Java standard library, which almost always prefers exceptions, even for expected errors such as invalid user input (e.g. Scanner.nextInt). This, I believe, significantly influences developer opinions about when it is appropriate to throw an exception.
As a C++ programmer, I personally prefer to reserve exceptions for very "exceptional" circumstances, e.g. out of memory, out of disk-space, the apocalypse happened, etc. But I don't insist that this is the absolute correct way to do things.
I don't think, that exceptions should rarely be used. But.
Not all teams and projects are ready to use exceptions. Usage of exceptions requires high qualification of programmers, special technics and lack of big legacy non exception-safe code. If you have huge old codebase, then it almost always is not exception-safe. I'm sure that you do not want to rewrite it.
If you are going to use exceptions extensively, then:
be prepared to teach your people about what exception safety is
you should not use raw memory management
use RAII extensively
From the other hand, using exceptions in new projects with strong team may make code cleaner, easier to maintain, and even faster:
you will not miss or ignore errors
you haven't to write that checks of return codes, without actually knowing what to do with wrong code at low-level
when you are forced to write exception-safe code, it becomes more structured
EDIT 11/20/2009:
I was just reading this MSDN article on improving managed code performance and this part reminded me of this question:
The performance cost of throwing an exception is significant. Although structured exception handling is the recommended way of handling error conditions, make sure you use exceptions only in exceptional circumstances when error conditions occur. Do not use exceptions for regular control flow.
Of course, this is only for .NET, and it's also directed specifically at those developing high-performance applications (like myself); so it's obviously not a universal truth. Still, there are a lot of us .NET developers out there, so I felt it was worth noting.
EDIT:
OK, first of all, let's get one thing straight: I have no intention of picking a fight with anyone over the performance question. In general, in fact, I am inclined to agree with those who believe premature optimization is a sin. However, let me just make two points:
The poster is asking for an objective rationale behind the conventional wisdom that exceptions should be used sparingly. We can discuss readability and proper design all we want; but these are subjective matters with people ready to argue on either side. I think the poster is aware of this. The fact is that using exceptions to control program flow is often an inefficient way of doing things. No, not always, but often. This is why it's reasonable advice to use exceptions sparingly, just like it's good advice to eat red meat or drink wine sparingly.
There is a difference between optimizing for no good reason and writing efficient code. The corollary to this is that there's a difference between writing something that is robust, if not optimized, and something that is just plain inefficient. Sometimes I think when people argue over things like exception handling they're really just talking past each other, because they are discussing fundamentally different things.
To illustrate my point, consider the following C# code examples.
Example 1: Detecting invalid user input
This is an example of what I'd call exception abuse.
int value = -1;
string input = GetInput();
bool inputChecksOut = false;
while (!inputChecksOut) {
try {
value = int.Parse(input);
inputChecksOut = true;
} catch (FormatException) {
input = GetInput();
}
}
This code is, to me, ridiculous. Of course it works. No one's arguing with that. But it should be something like:
int value = -1;
string input = GetInput();
while (!int.TryParse(input, out value)) {
input = GetInput();
}
Example 2: Checking for the existence of a file
I think this scenario is actually very common. It certainly seems a lot more "acceptable" to a lot of people, since it deals with file I/O:
string text = null;
string path = GetInput();
bool inputChecksOut = false;
while (!inputChecksOut) {
try {
using (FileStream fs = new FileStream(path, FileMode.Open)) {
using (StreamReader sr = new StreamReader(fs)) {
text = sr.ReadToEnd();
}
}
inputChecksOut = true;
} catch (FileNotFoundException) {
path = GetInput();
}
}
This seems reasonable enough, right? We're trying to open a file; if it's not there, we catch that exception and try to open a different file... What's wrong with that?
Nothing, really. But consider this alternative, which doesn't throw any exceptions:
string text = null;
string path = GetInput();
while (!File.Exists(path)) path = GetInput();
using (FileStream fs = new FileStream(path, FileMode.Open)) {
using (StreamReader sr = new StreamReader(fs)) {
text = sr.ReadToEnd();
}
}
Of course, if the performance of these two approaches were actually the same, this really would be purely a doctrinal issue. So, let's take a look. For the first code example, I made a list of 10000 random strings, none of which represented a proper integer, and then added a valid integer string onto the very end. Using both of the above approaches, these were my results:
Using try/catch block: 25.455 seconds
Using int.TryParse: 1.637 milliseconds
For the second example, I did basically the same thing: made a list of 10000 random strings, none of which was a valid path, then added a valid path onto the very end. These were the results:
Using try/catch block: 29.989 seconds
Using File.Exists: 22.820 milliseconds
A lot of people would respond to this by saying, "Yeah, well, throwing and catching 10,000 exceptions is extremely unrealistic; this exaggerates the results." Of course it does. The difference between throwing one exception and handling bad input on your own is not going to be noticeable to the user. The fact remains that using exceptions is, in these two case, from 1,000 to over 10,000 times slower than the alternative approaches that are just as readable -- if not more so.
That's why I included the example of the GetNine() method below. It isn't that it's intolerably slow or unacceptably slow; it's that it's slower than it should be... for no good reason.
Again, these are just two examples. Of course there will be times when the performance hit of using exceptions is not this severe (Pavel's right; after all, it does depend on the implementation). All I'm saying is: let's face the facts, guys -- in cases like the one above, throwing and catching an exception is analogous to GetNine(); it's just an inefficient way of doing something that could easily be done better.
You are asking for a rationale as if this is one of those situations where everyone's jumped on a bandwagon without knowing why. But in fact the answer is obvious, and I think you know it already. Exception handling has horrendous performance.
OK, maybe it's fine for your particularly business scenario, but relatively speaking, throwing/catching an exception introduces way more overhead than is necessary in many, many cases. You know it, I know it: most of the time, if you're using exceptions to control program flow, you're just writing slow code.
You might as well ask: why is this code bad?
private int GetNine() {
for (int i = 0; i < 10; i++) {
if (i == 9) return i;
}
}
I would bet that if you profiled this function you'd find it performs quite acceptably fast for your typical business application. That doesn't change the fact that it's a horribly inefficient way of accomplishing something that could be done a lot better.
That's what people mean when they talk about exception "abuse."
All of the rules of thumb about exceptions come down to subjective terms. You shouldn't expect to get hard and fast definitions of when to use them and when not to. "Only in exceptional circumstances". Nice circular definition: exceptions are for exceptional circumstances.
When to use exceptions falls into the same bucket as "how do I know whether this code is one class or two?" It's partly a stylistic issue, partly a preference. Exceptions are a tool. They can be used and abused, and finding the line between the two is part of the art and skill of programming.
There are lots of opinions, and tradeoffs to be made. Find something that speaks to you, and follow it.
It's not that exceptions should rarely be used. It's just that they should only be thrown in exceptional circumstances. For example, if a user enters the wrong password, that's not exceptional.
The reason is simple: exceptions exit a function abruptly, and propagate up the stack to a catch block. This process is very computationally expensive: C++ builds its exception system to have little overhead on "normal" function calls, so when an exception is raised, it has to do a lot of work to find where to go. Moreover, since every line of code could possibly raise an exception. If we have some function f that raises exceptions often, we now have to take care to use our try/catch blocks around every call of f. That's a pretty bad interface/implementation coupling.
I mentioned this issue in an article on C++ exceptions.
The relevant part:
Almost always, using exceptions to affect the "normal" flow is a bad idea. As we already discussed in section 3.1, exceptions generate invisible code paths. These code paths are arguably acceptable if they get executed only in the error handling scenarios. However, if we use exceptions for any other purpose, our "normal" code execution is divided into a visible and invisible part and it makes code very hard to read, understand and extend.
My approach to error handling is that there are three fundamental types of errors:
An odd situation that can be handled at the error site. This might be if a user inputs an invalid input at a command line prompt. The correct behavior is simply to complain to the user and loop in this case. Another situation might be a divide-by-zero. These situations aren't really error situations, and are usually caused by faulty input.
A situation like the previous kind, but one that can't be handled at the error site. For instance, if you have a function that takes a filename and parses the file with that name, it might not be able to open the file. In this case, it can't deal with the error. This is when exceptions shine. Rather than use the C approach (return an invalid value as a flag and set a global error variable to indicate the problem), the code can instead throw an exception. The calling code will then be able to deal with the exception - for instance to prompt the user for another filename.
A situation that Should Not Happen. This is when a class invariant is violated, or a function receives an invalid paramter or the like. This indicates a logic failure within the code. Depending on the level of failure, an exception may be appropriate, or forcing immediate termination may be preferable (as assert does). Generally, these situations indicate that something has broken somewhere in the code, and you effectively cannot trust anything else to be correct - there may be rampant memory corruption. Your ship is sinking, get off.
To paraphrase, exceptions are for when you have a problem you can deal with, but you can't deal with at the place you notice it. Problems you can't deal with should simply kill the program; problems you can deal with right away should simply be dealt with.
I read some of the answers here.
I'm still amazed on what all this confusion is about.
I strongly disagree with all this exceptions==spagetty code.
With confusion I mean, that there are people, which don't appreciate C++ exception handling.
I'm not certain how I learned about C++ exception handling -- but I understood the implications within minutes.
This was around 1996 and I was using the borland C++ compiler for OS/2.
I never had a problem to decide, when to use exceptions.
I usually wrap fallible do-undo actions into C++ classes.
Such do-undo actions include:
creating/destroying a system handle (for files, memory maps, WIN32 GUI handles, sockets, and so on)
setting/unsetting handlers
allocating/deallocating memory
claiming/releasing a mutex
incrementing/decrementing a reference count
showing/hiding a window
Than there are functional wrappers. To wrap system calls (which do not fall into the former category) into C++. E.g. read/write from/to a file.
If something fails, an exception will be thrown, which contains full information about the error.
Then there is catching/rethrowing exceptions to add more information to a failure.
Overall C++ exception handling leads to more clean code.
The amount of code is drasticly reduced.
Finally one can use a constructor to allocate fallible resources and still maintain a corruption free environment after such a failure.
One can chain such classes into complex classes.
Once a constructor of some member/base object is exectued, one can rely on that all other constructors of the same object (executed before) executed successfully.
Exceptions are a very unusual method of flow control compared to the traditional constructs (loops, ifs, functions, etc.) The normal control flow constructs (loops, ifs, function calls, etc.) can handle all the normal situations. If you find yourself reaching for an exception for a routine occurrence, then perhaps you need to consider how your code is structured.
But there are certain types of errors that cannot be handled easy with the normal constructs. Catastrophic failures (like resource allocation failure) can be detected at a low level but probably can't be handled there, so a simple if-statement is inadequate. These types of failures generally need to be handled at a much higher level (e.g., save the file, log the error, quit). Trying to report an error like this through traditional methods (like return values) is tedious and error-prone. Furthermore, it injects overhead into layers of mid-level APIs to handle this bizarre, unusual failure. The overhead distracts client of these APIs and requires them to worry about issues that are beyond their control. Exceptions provide a way to do non-local handling for big errors that's mostly invisible to all the layers between the detection of the problem and the handler for it.
If a client calls ParseInt with a string, and the string doesn't contain an integer, then the immediate caller probably cares about the error and knows what to do about it. So you'd design ParseInt to return a failure code for something like that.
On the other hand, if ParseInt fails because it couldn't allocate a buffer because memory is horribly fragmented, then the caller isn't going to know what to do about that. It would have to bubble this unusual error up and up to some layer that deals with these fundamental failures. That taxes everyone in between (because they have to accommodate the error passing mechanism in their own APIs). An exception makes it possible to skip over those layers (while still ensuring necessary clean-up happens).
When you're writing low-level code, it can be hard to decide when to use traditional methods and when to throw exceptions. The low-level code has to make the decision (throw or not). But it's the higher level code that truly knows what's expected and what's exceptional.
There's several reasons in C++.
First, it's frequently hard to see where exceptions are coming from (since they can be thrown from almost anything) and so the catch block is something of a COME FROM statement. It's worse than a GO TO, since in a GO TO you know where you're coming from (the statement, not some random function call) and where you're going (the label). They're basically a potentially resource-safe version of C's setjmp() and longjmp(), and nobody wants to use those.
Second, C++ doesn't have garbage collection built in, so C++ classes that own resources get rid of them in their destructors. Therefore, in C++ exception handling the system has to run all the destructors in scope. In languages with GC and no real constructors, like Java, throwing exceptions is a lot less burdensome.
Third, the C++ community, including Bjarne Stroustrup and the Standards Committee and various compiler writers, has been assuming that exceptions should be exceptional. In general, it's not worth going against language culture. The implementations are based on the assumption that exceptions will be rare. The better books treat exceptions as exceptional. Good source code uses few exceptions. Good C++ developers treat exceptions as exceptional. To go against that, you'd want a good reason, and all the reasons I see are on the side of keeping them exceptional.
This is a bad example of using exceptions as control flow:
int getTotalIncome(int incomeType) {
int totalIncome= 0;
try {
totalIncome= calculateIncomeAsTypeA();
} catch (IncorrectIncomeTypeException& e) {
totalIncome= calculateIncomeAsTypeB();
}
return totalIncome;
}
Which is very bad, but you should be writing:
int getTotalIncome(int incomeType) {
int totalIncome= 0;
if (incomeType == A) {
totalIncome= calculateIncomeAsTypeA();
} else if (incomeType == B) {
totalIncome= calculateIncomeAsTypeB();
}
return totalIncome;
}
This second example obviously needs some refactoring (like using the design pattern strategy), but illustrates well that exceptions are not meant for control flow.
Exceptions also have some performance penalties associated, but performance problems should follow the rule: "premature optimization is the root of all evil"
Maintainability: As mentioned by people above, throwing exceptions at a drop of a hat is akin to using gotos.
Interoperability: You can't interface C++ libraries with C/Python modules (atleast not easily) if you are using exceptions.
Performance degradation: RTTI is used to actually find the type of the exception which imposes additional overhead. Thus exceptions are not suitable for handling commonly occurring use cases(user entered int instead of string etc).
I would say that exceptions are a mechanism to get you out of current context (out of current stack frame in the simplest sense, but it's more than that) in a safe way. It's the closest thing structured programming got to a goto. To use exceptions in the way they were intended to be used, you have to have a situation when you can't continue what you're doing now, and you can't handle it at the point where you are now. So, for example, when user's password is wrong, you can continue by returning false. But if the UI subsystem reports that it can't even prompt the user, simply returning "login failed" would be wrong. The current level of code simply does not know what to do. So it uses an exception mechanism to delegate the responsibility to someone above who may know what to do.
One very practical reason is that when debugging a program I often flip on First Chance Exceptions (Debug -> Exceptions) to debug an application. If there are a lot of exceptions happening it's very difficult to find where something has gone "wrong".
Also, it leads to some anti-patterns like the infamous "catch throw" and obfuscates the real problems. For more information on that see a blog post I made on the subject.
I prefer to use exceptions as little as possible. Exceptions force the developer to handle some condition that may or may not be a real error. The definition of whether the exception in question is a fatal problem or a problem that must be handled immediately.
The counter argument to that is it just requires lazy people to type more in order to shoot themselves in their feet.
Google's coding policy says to never use exceptions, especially in C++. Your application either isn't prepared to handle exceptions or it is. If it isn't, then the exception will probably propagate it up until your application dies.
It's never fun to find out some library you have used throws exceptions and you were not prepared to handle them.
Legitimate case to throw an exception:
You try to open a file, it's not there, a FileNotFoundException is thrown;
Illegitimate case:
You want to do something only if a file doesn't exist, you try to open the file, and then add some code to the catch block.
I use exceptions when I want to break the flow of the application up to a certain point. This point is where the catch(...) for that exception is. For example, it's very common that we have to process a load of projects, and each project should be processed independently of the others. So the loop that process the projects has a try...catch block, and if some exception is thrown during the project processing, everything is rolled back for that project, the error is logged, and the next project is processed. Life goes on.
I think you should use exceptions for things like a file that doesn't exist, an expression that is invalid, and similar stuff. You should not use exceptions for range testing/ data type testing/ file existence/ whatever else if there's an easy/ cheap alternative to it. You should not use exceptions for range testing/ data type testing/ file existence/ whatever else if there's an easy/ cheap alternative to it because this sort of logic makes the code hard to understand:
RecordIterator<MyObject> ri = createRecordIterator();
try {
MyObject myobject = ri.next();
} catch(NoSuchElement exception) {
// Object doesn't exist, will create it
}
This would be better:
RecordIterator<MyObject> ri = createRecordIterator();
if (ri.hasNext()) {
// It exists!
MyObject myobject = ri.next();
} else {
// Object doesn't exist, will create it
}
COMMENT ADDED TO THE ANSWER:
Maybe my example wasn't very good - the ri.next() should not throw an exception in the second example, and if it does, there's something really exceptional and some other action should be taken somewhere else. When the example 1 is heavily used, developers will catch a generic exception instead of the specific one and assume that the exception is due to the error that they're expecting, but it can be due to something else. In the end, this leads to real exceptions being ignored as exceptions became part of the application flow, and not an exception to it.
The comments on this may add more than my answer itself.
Basically, exceptions are an unstructured and hard to understand form of flow control. This is necessary when dealing with error conditions that are not part of the normal program flow, to avoid having error handling logic clutter up the normal flow control of your code too much.
IMHO exceptions should be used when you want to provide a sane default in case the caller neglects to write error handling code, or if the error might best be handled further up the call stack than the immediate caller. The sane default is to exit the program with a reasonable diagnostic error message. The insane alternative is that the program limps along in an erroneous state and crashes or silently produces bad output at some later, harder to diagnose point. If the "error" is enough a normal part of program flow that the caller could not reasonably forget to check for it, then exceptions should not be used.
I think, "use it rarely" ist not the right sentence. I would prefer "throw only in exceptional situations".
Many have explained, why exceptions should not used in normal situations. Exceptions have their right for error handling and purely for error handling.
I will focus on an other point:
An other thing is the performance issue. Compilers struggled long to get them fast. I am not sure, how the exact state is now, but when you use exceptions for control flow, than you will get an other trouble: Your program will become slow!
The reason is, that exceptions are not only very mighty goto-statements, they also have to unwind the stack for all the frames they leave. Thus implicitely also the objects on stack have to be deconstructed and so on. So without be aware of it, one single throw of an exception will really get a whole bunch of mechanics be involved. The processor will have to do a mighty lot.
So you will end up, elegantly burning your processor without knowing.
So: use exceptions only in exceptional cases -- Meaning: When real errors occured!
The purpose of exceptions is to make software fault tolerant. However having to provide a response to every exception thrown by a function leads to suppression. Exceptions are just a formal structure forcing programmers to acknowledge that certain things can go wrong with a routine and that the client programmer needs to be aware of these conditions and cater for them as necessary.
To be honest, exceptions are a kludge added to programming languages to provide developers with some formal requirement that shifts the responsibility of handling error cases from the immediate developer to some future developer.
I believe that a good programming language does not support exceptions as we know them in C++ and Java. You should opt for programming languages that can provide alternative flow for all sorts of return values from functions. The programmer should be responsible for anticipating all forms of outputs of a routine and handle them in a seperate code file if I could have my way.
I use exceptions if:
an error occured that cannot be recovered from locally AND
if the error is not recovered from the program should terminate.
If the error can be recovered from (the user entered "apple" instead of a number) then recover (ask for the input again, change to default value, etc.).
If the error cannot be recovered from locally but the application can continue (the user tried to open a file but the file does not exist) then an error code is appropriate.
If the error cannot be recovered from locally and the application cannot continue without recovering (you are out of memory/disk space/etc.), then an exception is the right way to go.
Who said they should be used conservatively ? Just never use exceptions for flow control and thats it.
And who cares about the cost of exception when it already thrown ?
My two cents:
I like to use exceptions, because it allows me to program as if no errors will happen. So my code remains readable, not scattered with all kinds of error-handling. Of course, the error handling (exception handling) is moved to the end (the catch block) or is considered the responsability of the calling level.
A great example for me, is either file handling, or database handling. Presume everything is ok, and close your file at the end or if some exception occurs. Or rollback your transaction when an exception occurred.
The problem with exceptions, is that it quickly gets very verbose. While it was meant to allow your code to remain very readable, and just focus on the normal flow of things, but if used consistently almost every function call needs to be wrapped in a try/catch block, and it starts to defeat the purpose.
For a ParseInt as mentioned before, i like the idea of exceptions. Just return the value. If the parameter was not parseable, throw an exception. It makes your code cleaner on the one hand. At the calling level, you need to do something like
try
{
b = ParseInt(some_read_string);
}
catch (ParseIntException &e)
{
// use some default value instead
b = 0;
}
The code is clean. When i get ParseInt like this scattered all over, i make wrapper functions that handle the exceptions and return me default values. E.g.
int ParseIntWithDefault(String stringToConvert, int default_value=0)
{
int result = default_value;
try
{
result = ParseInt(stringToConvert);
}
catch (ParseIntException &e) {}
return result;
}
So to conclude: what i missed througout the discussion was the fact that exceptions allow me to make my code easier/more readable because i can ignore the error conditions more. Problems:
the exceptions still need to be handled somewhere. Extra problem: c++ does not have the syntax that allows it to specify which exceptions a function might throw (like java does). So the calling level is not aware which exceptions might need to be handled.
sometimes code can get very verbose, if every function needs to be wrapped in a try/catch block. But sometimes this still makes sense.
So that makes it hard to find a good balance sometimes.
I'm sorry but the answer is "they are called exceptions for a reason." That explanation is a "rule of thumb". You can't give a complete set of circumstances under which exceptions should or should not be used because what a fatal exception (English definition) is for one problem domain is normal operating procedure for a different problem domain. Rules of thumb are not designed to be followed blindly. Instead they are designed to guide your investigation of a solution. "They are called exceptions for a reason" tells you that you should determine ahead of time what is a normal error the caller can handle and what is an unusual circumstance the caller cannot handle without special coding (catch blocks).
Just about every rule of programming is really a guideline saying "Don't do this unless you have a really good reason": "Never use goto", "Avoid global variables", "Regular expressions pre-increment your number of problems by one", etc. Exceptions are no exception....

Can I use the STL if I cannot afford the slow performance when exceptions are thrown?

For example, I'm writing a multi-threaded time-critical application that processes and streams audio in real-time. Interruptions in the audio are totally unacceptable. Does this mean I cannot use the STL because of the potential slow down when an exception is thrown?
Generally, the only exceptions that STL containers will throw by themselves is an std::bad_alloc if new fails. The only other times are when user code (for example constructors, assignments, copy constructors) throws. If your user code never throws then you only have to guard against new throwing, which you would have had to do anyways most likely.
Other things that can throw exceptions:
- at() functions can throw std::out_of_range if you access them out of bounds. This is a serious program error anyways.
Secondly, exceptions aren't always slow. If an exception occurs in your audio processing, its probably because of a serious error that you will need to handle anyways. The error handling code is probably going to be significantly more expensive than the exception handling code to transport the exception to the catch site.
If an STL container throws, you are probably having much bigger problem than the slow down :)
It's not clearly written in the previous answers, so:
Exceptions happen in C++
Using the STL or not won't remove the RAII code that will free the objects's resources you allocated.
For example:
void doSomething()
{
MyString str ;
doSomethingElse() ;
}
In the code above, the compiler will generate the code to free the MyString resources (i.e. will call the MyString destructor), no matter what happens in the meantime including if if an exception is thrown by doSomethingElse or if you do a "return" before the end of the function scope.
If you have a problem with that, then either you should revise your mindset, or try C.
Exceptions are supposed to be exceptional
Usually, when an exception occurs (and only when), you'll have a performance hit.
But then, the exception should only sent when:
You have an exceptional event to handle (i.e. some kind of error)
In very exceptional cases (i.e. a "massive return" from multiple function call in the stack, like when doing a complicated search, or unwinding the stack prior a thread graceful interruption)
The keyword here is "exceptional", which is good because we are discussing "exception" (see the pattern?).
In your case, if you have an exception thrown, chances are good something so bad happened your program would have crashed anyway without exception.
In this case, your problem is not dealing with the performance hit. It is to deal with a graceful handling of the error, or, at worse, graceful termination of your program (including a "Sorry" messagebox, saving unsaved data into a temporary file for later recovery, etc.).
This means (unless in very exceptional cases), don't use exceptions as "return data". Throw exceptions when something very bad happens. Catch an exception only if you know what to do with that. Avoid try/catching (unless you know how to handle the exception).
What about the STL ?
Now that we know that:
You still want to use C++
Your aim is not to throw thousand exceptions each and every seconds just for the fun of it
We should discuss STL:
STL will (if possible) usually verify if you're doing something wrong with it. And if you do, it will throw an exception. Still, in C++, you usually won't pay for something you won't use.
An example of that is the access to a vector data.
If you know you won't go out of bounds, then you should use the operator [].
If you know you won't verify the bounds, then you should use the method at().
Example A:
typedef std::vector<std::string> Vector ;
void outputAllData(const Vector & aString)
{
for(Vector::size_type i = 0, iMax = aString.size() ; i != iMax ; ++i)
{
std::cout << i << " : " << aString[i] << std::endl ;
}
}
Example B:
typedef std::vector<std::string> Vector ;
void outputSomeData(const Vector & aString, Vector::size_type iIndex)
{
std::cout << iIndex << " : " << aString.at(iIndex) << std::endl ;
}
The example A "trust" the programmer, and no time will be lost in verification (and thus, less chance of an exception thrown at that time if there is an error anyway... Which usually means the error/exception/crash will usually happen after, which won't help debugging and will let more data be corrupted).
The example B asks the vector to verify the index is correct, and throw an exception if not.
The choice is yours.
Do not be afraid of exceptions with regard to performance.
In the old days of C++ a build with exceptions enabled could be a lot slower on some compilers.
These days it really does not matter if your build with or without exception handling.
In general STL does not throw exceptions unless you run out of memory so that should not be a problem for your type of application either.
(Now do not use a language with GC.....)
It's worth noting a couple of points:
Your application is multi-threaded. If one thread (maybe a GUI one) is slowed down by an exception, it should not affect the performance of the real-time threads.
Exceptions are for exceptional circumstances. If an exception is thrown in your real-time thread, the chances are it will mean that you couldn't continue playing audio anyway. If you find for whatever reason that you are continually processing exceptions in those threads, redesign to avoid the exceptions in the first place.
I'd recommend you accept the STL with it's exceptions (unless the STL itself proves too slow - but remember: measure first, optimise second), and also to adopt exception handling for your own 'exceptional situations' (audio hardware failure, whatever) in your application.
I'm struggling to think which portions of the STL specify that they can raise an exception. In my experience most error handling is handled by return codes or as a prerequisite of the STL's use.
An object passed to the STL could definitely raise an exception, e.g. copy constructor, but that would be an issue regardless of the use of STL.
Others have mentioned functions such as std::vector::at() but you can perform a check or use an alternate method usually to ensure no exception can be thrown.
Certainly a particular implementation of the STL can performs "checks", generally for debug builds, on your use of the STL, I think it will raise an assertion only, but perhaps some will throw an exception.
If there is no try/catch present I believe no/minimal performance hit will be incurred unless an exception is raised by your own classes.
On Visual Studio you can disable the use of C++ exceptions entirely see Project Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions. I presume this is available on most C++ platforms.
You talk as if exceptions are inevitable. Simply don't do anything that could cause an exception -- fix your bugs, verify your inputs.