I just read that in the C++11 standard revision, exception specifications were deprecated. I previously thought specifying what your functions may throw is good practice, but apparently, not so.
After reading Herb Stutter's well-cited article, I cannot help but wonder: why on earth are exception specifications implemented the way they are, and why has the committee decided to deprecate them instead of having them checked at compile-time? Why would a compiler even allow an exception to be thrown which doesn't appear in the function definition? To me, this all sounds like saying "You probably shouldn't specify your function return type, because when you specify int f()
, but return 3.5;
inside of it, your program will likely crash." (i. e., where is the conceptual difference from strong typing?)
(For the lack of exception specification support in typedef
s, given that template syntax is probably Turing-complete, implementing this sounds easy enough.)
The original reason was that it was deemed impossible to reliably check given the body of existing code, and the fact that no specifier means anything can throw. Which means that if static checking was in force, the following code wouldn't compile:
double
safeSquareRoot( double d ) throw()
{
return d > 0.0 ? sqrt( d ) : 0.0;
}
Also, the purpose of exceptions are to report errors over a great distance, which means that the intermediate functions shouldn't know what the functions they call might throw. Requiring exception specifiers on them would break encapsulation.
The only real case where a function needs to know about the
exceptions that might occur is to know what exceptions cannot
occur. In particular, it is impossible to write thread safe code
unless you can be guaranteed that some functions will never
throw. Even here, static checking isn't acceptable, for the
reasons explained above, so the exception specification is
designed to work more like an assertion that you cannot
disactivate: when you write throw()
, you get more or less the
equivalent of an assertion failure if the function is terminated
by an exception.
The situation in Java is somewhat different. In Java,
there are no real out parameters, which means that if you can't
use return codes if the function also has a return value. The
result is that exceptions are used in a lot of cases where
a return code would be preferable. And these, you do have to
know about, and handle immediately. For things that should
really be exceptions, Java has java.lang.RuntimeException
(which isn't checked, statically or otherwise). And it has no
way of saying that a function cannot ever throw an exception; it
also uses unchecked exceptions (called Error
) in cases where
aborting the program would be more appropriate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With