Sometimes, just because you can do something doesn’t mean you should. Unfortunately, the C++ Standards Council missed that memo when they ratified the exception specifiers. To find out why, try this little quiz.
Question: This code contains a fatal flaw (literally), but can you see why?
void bar(); // declaration void foo() throw() { bar(); }
Answer: The call to bar() cause the application to terminate.
Why?
The function foo() has an empty throw exception specifier, meaning it guarantees it will not percolate any exceptions. So far so good. Now, look at bar(). That doesn’t have a throw exception specifier, meaning it makes no guarantees about whether it will or won’t percolate any exceptions. So, what happens if bar() does percolate an exception?
Well, under normal circumstances the behaviour is very well defined; your application will be immediately terminated. That’s right, terminate! No passing go, no collecting your £200. It’s goodnight Vienna!
You see, a throw specifier doesn’t actually guarantee a function won’t percolate an exception. All it does is indicate that the function shouldn’t throw an exception. If an exception does percolates from the function the C++ runtime calls the unexpected() function. By default this function just calls the terminate() function, and it should be pretty obvious what that will do.
Now as it happens you can change this behaviour by making a call to the set_unexpected() function to register your own callback, but what exactly are you going to do? There is no way to just continue unwinding the stack as if nothing happened so you’re pretty stuck with the only sensible thing being to terminate the application (hence, this being the default behaviour).
Considering all this, why oh why bother using exception specifiers? They don’t actually guarantee anything. All they do is make your code unsafe as you are basically subscribing to a time-bomb waiting to happen!
NB. Some compilers vendors (Microsoft, I am looking at you) don’t actually implement the correct behaviour for exception specifiers. Basically, they just ignore them. Now, one might argue that’s probably not a bad thing but I disagree. Regardless of how stupid exception specifiers are the fact is that at least the behaviour is well defined by the C++ Standard. A compiler doing it’s own thing means you don’t know what’s actually going to happen and this is worse! As far as I’m concerned, if a compiler isn’t standards compliant it is broken, end of!