In C++ you may declare function with exception specification like this:
int foo() const throw(Exception);
I found those two links:
- http://www.cplusplus.com/doc/tutorial/exceptions/ and
- http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr156.htm
But several things end up unanswered…
Question 1: why to add exception specification? Will it bring any performance increase? What will be different for compiler? Because it seems just like an information for programmer to me.
Question 2: what will happend (what should happen) if I throw something that isn’t in specification? For example:
int foo() throw(int) {
throw char; // Totally unrelated classes, not types in real
}
Question 3: function/method shouldn’t throw anything. I found at least two (three, alternative syntax for different compilers) ways to specify no exception throwing:
int foo() throw();int foo() __attribute(nothrow)__for gccint foo() nothrowfor visual C++
Which one is “correct”? Is there any difference? Which one should I use?
Question 4: “standart exceptions”, bad_alloc,bad_cast,bad_exception,bad_typeid and ios_base::failure.
Ok bad_alloc is self explaining and I know how (and more importantly when) to use it (add to exception specification), but what about the others? None of them does really ring a bell… Which “code pieces” are they associated with? Like bad_alloc is associated with new char[500000].
Question 5: If I have exception classes hierarchy, like this:
class ExceptionFileType {
virtual const char * getError() const = 0;
};
class ExceptionFileTypeMissing : public ExceptionFileType {
virtual const char *getError() cosnt {
return "Missing file";
}
}
Should I use:
int foo() throw(ExceptionFileType);
Or:
int foo() throw(ExceptionFileTypeMissing,ExceptionFileTypeNotWritable,ExceptionFileTypeNotReadable,...)
Note: answers with references would be great. I’m looking for good practice tips.
The simple “good practice” tip is: don’t use exception specifications.
Essentially the only exception to that is the possibility of an empty exception specification:
throw(). That’s sufficiently useful that in C++11 it’s been given its own keyword (noexcept). It’s generally agreed that any non-empty exception specification is a lousy idea though.Exception specifications (other than
noexcept) are officially deprecated — and unlike many deprecated features, removing this would affect little enough source code that I think there’s a good chance it really will eventually be removed (certainly no guarantee, but a pretty fair chance anyway).As for what happens when/if you do throw an exception of a type not allowed by the exception specification:
std::unexpected()gets invoked. By default, that invokesterminate(). You can usestd::set_unexpectedto set your own handler — but about all you can reasonably do is add some logging before youterminate(). Your unexpected handler is not allowed to return.