Is there a reference about C++ Standard Library Exceptions? I just want to know that which functions may throw an exception or not.
Actually, most of the standard library function don't throw exceptions themselves. They just pass on exception thrown by user code invoked by them. For example, if you push_back() an element to a vector, this can throw (due to memory allocation errors and) if the object's copy constructor throws.
A few notable exceptions (no pun intended) where library functions throw are:
Some methods will throw out_of_range if the index provided is invalid:
std::vector<>::at()
std::basic_string<>::at()
std::bitset<>::set(), reset() and flip().
Some methods will throw std::overflow_error on integer overflow:
std::bitset<>::to_ulong() and (C++0x) to_ullong().
std::allocator<T> will pass on std::bad_alloc thrown by new which it invokes.
Streams can be setup so that std::ios_base::failure are thrown when a state bit is set.
Large array allocations can throw std::bad_array_new_length
dynamic_cast on a reference can throw a std::bad_cast (technically not part of the standard library)
Throwing an invalid exception from a function with an exception specification will throw a std::bad_exception
Calling a std::function::operator(...) if it has no value will throw std::bad_function_call.
Using typeinfo of a null pointer may throw a std::bad_typeid.
Accessing a weak_ptr after the pointee has been released will throw a std::bad_weak_ptr.
Incorrect usage of std::promise/std::future may throw a std::future_error.
(c++11) The string conversion functions std::stoi, std::stol, std::stoll, std::stoul, std::stoull, std::stof, std::stod, and std::stold can throw both std::invalid_argument and std::out_of_range.
(c++11) In the regex family, constructors and assign methods can throw std::regex_error.
(I'm making this a CW answer, so if anyone can think of more such, please feel free to append them here.)
Also, for the 3rd edition of The C++ Programming Language, Bjarne Stroustrup has a downloadable appendix about exception safety, which might be relevant.
The only functions guaranteed (by the compiler) to not throw are functions that have the throw() exception specification, like this:
void ThisFunctionNeverThrows() throw()
{
}
Otherwise, any other function can potentially throw an exception, unless they are specifically documented otherwise. You must consider exception safety when writing code in the face of exceptions.
See Bjarne Stroustup's article on exception safety and the standard library: http://www2.research.att.com/~bs/3rd_safe.pdf Starting on page 19 in the PDF you can find information on guarantees made by the standard containers.
Related
According to Optimizing C++,
Use the empty exception specification (that is, append throw() to the declaration) for the functions you are sure will never throw exceptions.
What if I know that 90% of my methods won't throw an exception? It seems unconventional and verbose to append throw() to all of those methods. If not, what are the advantages? Or am I misunderstanding something here?
C++11 has introduced noexcept, throw is somewhat deprecated (and according to this less efficient)
noexcept is an improved version of throw(), which is deprecated in C++11. Unlike throw(), noexcept will not call std::unexpected and may or may not unwind the stack, which potentially allows the compiler to implement noexcept without the runtime overhead of throw().
When an empty throw specification is violated, your program is terminated; this means you should only declare your functions as non throwing, only when they have a no throw exception guarantee.
Finally you need a move constructor to be non throwing (specified with noexcept) to be able to use the r-value ref version of std::vector<T>::push_back (see a better explanation here)
The standard throw() doesn't enhance optimizability.
If a method is marked as throw() then the compiler is forced to check if an exception is thrown from the method and unwind the stack - just like if the function is not marked as throw(). The only real difference is that for a function marked throw() the global unexpected_handler will be called (which generally calls terminate()) when the exception leaves the function, unwinding the stack to that level, instead of the behavior for functions without an exception specification which will handle the exception normally.
For pre-C++11 code, Sutter & Alexandrescu in "C++ Coding Standards" suggested:
Avoid exception specifications.
Take exception to these specifications: Don’t write exception
specifications on your functions unless you’re forced to (because
other code you can’t change has already introduced them; see
Exceptions).
...
A common but nevertheless incorrect belief is that exception
specifications statically guarantee that functions will throw only
listed exceptions (possibly none), and enable compiler optimizations
based on that knowledge
In fact, exception specifications actually do something slightly but
fundamentally different: They cause the compiler to inject additional
run-time overhead in the form of implicit try/catch blocks around the
function body to enforce via run-time checking that the function does
in fact emit only listed exceptions (possibly none), unless the
compiler can statically prove that the exception specification can
never be violated in which case it is free to optimize the checking
away. And exception specifications can both enable and prevent further
compiler optimizations (besides the inherent overhead already
described); for example, some compilers refuse to inline functions
that have exception specifications.
Note that in some versions of Microsoft's compilers (I'm not sure if this behavior has changed in more recent versions, but I don't think so), throw() is treated in a non-standard way. throw() is equivalent to __declspec(nothrow) which does allow the compiler to assume that the function will not have an exception thrown and undefined behavior will result if one is.
C++11 deprecates the C++98 style exception specification and introduced the noexcept keyword. Bjarne Stroustup's C++11 FAQ says this about it:
If a function declared noexcept throws (so that the exception tries to
escape, the noexcept function) the program is terminated (by a call to
terminate()). The call of terminate() cannot rely on objects being in
well-defined states (i.e. there is no guarantees that destructors have
been invoked, no guaranteed stack unwinding, and no possibility for
resuming the program as if no problem had been encountered). This is
deliberate and makes noexcept a simple, crude, and very efficient
mechanism (much more efficient than the old dynamic throw()
mechanism).
In C++11 if an exception is thrown from a function marked as noexcept the compiler is not obligated to unwind the stack at all. This affords some optimization possibilities. Scott Meyers discusses the new noexcept in his forthcoming book "Effective Modern C++".
Just as I can see in cppreference, the classic "throw" declaration lists is now deprecated in C++11. What is the reason of leaving this mechanism and how should I have to specify what exceptions throws a function of mine?
For more detailed reasoning, see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html
As expressed in the national body comment above, exception specifications have not proven useful in practice. There are numerous discussions of the problems with exception specifications in C++ (see, e.g., [Sutter02], [Boost03]), but the main issues are:
Run-time checking: C++ exception specifications are checked at runtime rather than at compile time, so they offer no programmer guarantees that all exceptions have been handled. The run-time failure mode (calling std::unexpected()) does not lend itself to recovery.
Run-time overhead: Run-time checking requires the compiler to produce additional code that also hampers optimizations.
Unusable in generic code: Within generic code, it is not generally possible to know what types of exceptions may be thrown from operations on template arguments, so a precise exception specification cannot be written.
In practice, only two forms of exception-throwing guarantees are useful: an operation might throw an exception (any exception) or an operation will never throw any exception. The former is expressed by omitting the exception-specification entirely, while the latter can be expressed as throw() but rarely is, due to performance considerations.
[N3050] introduces a new kind of exception specification, noexcept, the specifies that the function will not throw any exceptions. Unlike throw(), noexcept does not require the compiler to introduce code to check whether an exception is thrown. Rather, if a function specified as noexcept is exited via an exception, the result is a call to std::terminate().
With the introduction of noexcept, programmers can now express the two kinds of exception guarantees that are useful in practice, without additional overhead. This paper therefore proposes to deprecate "dynamic" exception specifications, i.e., those that are written as throw(type-id-listopt).
The answer Peter gave does not hit the actual problem of exception specifications for the implementor and user:
Exception specifications cause the program to terminate (or more precisely call termination handlers) if the implementor failed to uphold the guarantee to only throw the defined exceptions.
Thus by calling a method with a exception specification you as a library user are making your own code more prone to complete failure/termination. If the library function runs out-of-memory (std::bad_alloc), you will not get a chance to catch, but you will be terminated instead.
Thus, the original goal of communicating the most likely failure options and asking you as the user to handle them was not achieved.
As an implementor on the other side, you cannot really call any other methods any more which do not have exception specifications, because these might cause you to terminate your callers. A terrible place to be in.
The conclusion is that C++ should have just gone the way that Java did it:
If you call a method with exception specification and you have an exception specification yourself, then you must catch the exception or specify it in your own exception specification.
The compiler enforces this and no other runtime effects.
Noexcept (since C++11) suffers the same conceptual mistake, since it will also cause run-time termination if the specification is not adhered too, i.e. a method throws that was declared not to. This makes noexcept impossible to use for anything serious but the most contained cases (move constructors come to mind).
They produce slower and bigger code, because libc++ has to check if any exception propagating out of a function violates it's exception specification and call std::unexpected. This is hardly ever useful, and is worse than just documenting the exceptions a function throws yourself.
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 gcc
int foo() nothrow for 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 invokes terminate(). You can use std::set_unexpected to set your own handler -- but about all you can reasonably do is add some logging before you terminate(). Your unexpected handler is not allowed to return.
Question 1
Don't bother. They were a bad idea, and were deprecated in the latest version of the language. They give no benefit to the compiler, since they are checked at runtime; if anything, they might hurt performance in some cases.
Question 2
A function called std::unexpected will be called. By default, this calls std::terminate; by default, that terminates the program. Both of these behaviours can be changed, using std::set_unexpected and std::set_terminate to install your own handler, if you really want to.
Question 3
throw() was the standard way to do it; the others are non-portable compiler extensions. In C++11, you might use noexcept, which gives a compile-time check that nothing can throw, rather than a run-time check that nothing does throw.
Question 4
bad_cast is thrown when a dynamic_cast of a reference fails.
bad_exception is thrown in some weird circumstances when an exception specification is violated.
bad_typeid is thrown if evaluating the argument to typeid involves dereferencing a null pointer
ios_base::failure is thrown by the input/output library (<iostream> etc.) when some operations fail
Question 5
If you want to allow the entire heirarchy to be thrown, then just specify the base class. But you shouldn't be using exception specifiers at all.
First, let's be very clear what an exception specification does: it's
more or less like an assert that can't be disabled, asserting that you
will not exit the function with an exception other than the ones
missing. As such, it's utility is far more limited than it would seem
at first; for the most part (and in this case, I can't imagine an
exception), the only really useful guarantee is throw(), which
guarantees that no exception will be thrown; if you want to write
exception safe code, you'll need this guarantee for a few low level
functions.
In practice, although throw() could allow some additional compiler
optimizations, the generic implementation tends to result in less
efficient code when an exception specification is used. In C++11, the
throw() has been replaced by noexcept, presumably with the hope that
compiler implementers will do something intelligent with it.
EDIT:
Since everyone (including myself) seems to have missed your question 4:
bad_alloc will be thrown by the operator new function if it cannot
allocate the memory.
bad_cast will be thrown by a dynamic_cast to a reference, in the
case where the cast fails. (A dynamic_cast to a pointer returns a
null pointer in such cases.)
bad_exception will be thrown when an exception specification is
violated, provided the exception specification allows bad_exception.
(In other words, forget it.)
bad_typeid will be thrown if you try to use typeid with a null
pointer.
ios_base::failure will be thrown if you request a stream to throw in
case of errors.
Practically speaking: you'll catch bad_alloc if you want to recover
and continue from out of memory situations. Which means not very often.
(It's very, very difficult to recover from an out of memory situation.)
For bad_cast, it's probably preferrable to use pointers, and test for
null, if you aren't sure. And there's no excuse for ever seeing a
bad_typeid. Most of the time, you'll probably want to test IO errors
explicitly, rather than configuring the stream to throw exceptions; and
exception when ios_base::badbit is set might be an exception (since it
represents a truly exceptional case of a hardward fault).
Questions 1 and 2 are addressed at some length in this question.
Questions 3 and 5 are covered by the recommendation, in the accepted answer to that question, that you don't use exception specifications at all.
Question 4 seems to be adequately addressed by typing those exception names into the search engine of your choice, or consulting the index of a good C++ book. Do you have a specific query about them?
I know the STL will throw on a memory allocation error or if the contained type throws in its constructor / assignment operator.
Otherwise, apparently 'a few' STL methods can throw other exceptions. The example everyone seems to mention is vector::at(), but I can't find a list of the others anywhere.
Does anyone know of such a list?
Won't be 100% accurate, and is for C++03, but a half-hour effort based on grepping through GCC 4.3.4 includes, ignoring tr1 and ext but including iostream. Crucially, some of these checks might be due to this implementation prefering more defensive coding, and might not be mandated in the Standard and available universally....
bitset
std::overflow_error - .to_ulong() when too many bits to fit in unsigned long
std::out_of_range - operator[]() attempt past end
new
std::bad_alloc
typeinfo
std::bad_cast on invalid dynamic_cast attempt
ios
std::ios_base::failure when using exception masks for error reporting
string
out_of_range - at/append/assign/insert/erase/replace/copy/substr
length_error: attempt to exceed max_size() during reserve or implicit resize (e.g. assign/insert/+= etc.)
locale
std::bad_cast if locale doesn't contain a facet of type Facet
std::runtime_error in various null-pointer/undefined-facet situations
deque/vector
length_error: attempt reserve() or implicitly-grow > max_size()
out_of_range: at()
map
std::out_of_range: at()
Well, I have this big, gigantic book titled, The C++ Standard, that contains a complete description of all functions in the standard library and what they can/cannot do.
In C++, you can specify that a function may or may not throw an exception by using an exception specifier. For example:
void foo() throw(); // guaranteed not to throw an exception
void bar() throw(int); // may throw an exception of type int
void baz() throw(...); // may throw an exception of some unspecified type
I'm doubtful about actually using them because of the following:
The compiler doesn't really enforce exception specifiers in any rigorous way, so the benefits are not great. Ideally, you would like to get a compile error.
If a function violates an exception specifier, I think the standard behaviour is to terminate the program.
In VS.Net, it treats throw(X) as throw(...), so adherence to the standard is not strong.
Do you think exception specifiers should be used?
Please answer with "yes" or "no" and provide some reasons to justify your answer.
No.
Here are several examples why:
Template code is impossible to write with exception specifications,
template<class T>
void f( T k )
{
T x( k );
x.x();
}
The copies might throw, the parameter passing might throw, and x() might throw some unknown exception.
Exception-specifications tend to prohibit extensibility.
virtual void open() throw( FileNotFound );
might evolve into
virtual void open() throw( FileNotFound, SocketNotReady, InterprocessObjectNotImplemented, HardwareUnresponsive );
You could really write that as
throw( ... )
The first is not extensible, the second is overambitious and the third is really what you mean, when you write virtual functions.
Legacy code
When you write code which relies on another library, you don't really know what it might do when something goes horribly wrong.
int lib_f();
void g() throw( k_too_small_exception )
{
int k = lib_f();
if( k < 0 ) throw k_too_small_exception();
}
g will terminate, when lib_f() throws. This is (in most cases) not what you really want. std::terminate() should never be called. It is always better to let the application crash with an unhandled exception, from which you can retrieve a stack-trace, than to silently/violently die.
Write code that returns common errors and throws on exceptional occasions.
Error e = open( "bla.txt" );
if( e == FileNotFound )
MessageUser( "File bla.txt not found" );
if( e == AccessDenied )
MessageUser( "Failed to open bla.txt, because we don't have read rights ..." );
if( e != Success )
MessageUser( "Failed due to some other error, error code = " + itoa( e ) );
try
{
std::vector<TObj> k( 1000 );
// ...
}
catch( const bad_alloc& b )
{
MessageUser( "out of memory, exiting process" );
throw;
}
Nevertheless, when your library just throws your own exceptions, you can use exception specifications to state your intent.
Avoid exception specifications in C++. The reasons you give in your question are a pretty good start for why.
See Herb Sutter's "A Pragmatic Look at Exception Specifications".
I think the standardly except convention (for C++)
Exception specifiers were an experiment in the C++ standard that mostly failed.
The exception being that the no throw specifier is useful but you should also add the appropriate try catch block internally to make sure the code matches the specifier. Herb Sutter has a page on the subject. Gotch 82
In a addition I think it is worth describing Exception Guarantees.
These are basically documentation on how the state of an object is affected by exceptions escaping a method on that object. Unfortunately they are not enforced or otherwise mentioned by the compiler.
Boost and Exceptions
Exception Guarantees
No Guarantee:
There is no guarantee about the state of the object after an exception escapes a method
In these situations the object should no longer be used.
Basic Guarantee:
In nearly all situations this should be the minimum guarantee a method provides.
This guarantees the object's state is well defined and can still be consistently used.
Strong Guarantee: (aka Transactional Guarantee)
This guarantees that the method will complete successfully
Or an Exception will be thrown and the objects state will not change.
No Throw Guarantee:
The method guarantees that no exceptions are allowed to propagate out of the method.
All destructors should make this guarantee.
| N.B. If an exception escapes a destructor while an exception is already propagating
| the application will terminate
gcc will emit warnings when you violate exception specifications. What I do is to use macros to use the exception specifications only in a "lint" mode compile expressly for checking to make sure the exceptions agree with my documentation.
The only useful exception specifier is "throw()", as in "doesn't throw".
Exception specifications are not wonderfully useful tools in C++. However, there /is/ a good use for them, if combined with std::unexpected.
What I do in some projects is code with exception specifications, and then call set_unexpected() with a function that will throw a special exception of my own design. This exception, upon construction, gets a backtrace (in a platform-specific manner) and is derived from std::bad_exception (to allow it to be propagated if desired). If it causes a terminate() call, as it usually does, the backtrace is printed by what() (as well as the original exception that caused it; not to hard to find that) and so I get information of where my contract was violated, such as what unexpected library exception was thrown.
If I do this, I never allow propagation of library exceptions (except std ones) and derive all my exceptions from std::exception. If a library decides to throw, I will catch and convert into my own hierarchy, allowing for me to always control the code. Templated functions that call dependent functions should avoid exception specifications for obvious reasons; but it's rare to have a templated function interface with library code anyway (and few libraries really use templates in a useful manner).
If you're writing code that will be used by people that would rather look at the function declaration than any comments around it, then a specification will tell them which exceptions they might want to catch.
Otherwise I don't find it particularly useful to use anything but throw() to indicate that it doesn't throw any exceptions.
Yes, if you're into internal documentation. Or maybe writing a libary that others will use, so that they can tell what happens without consulting the documentation. Throwing or not throwing can be considered part of the API, almost like the return value.
I agree, they are not really useful for enforcing correctness Java style in the compiler, but it's better than nothing or haphazard comments.
No. If you use them and an exception is thrown that you did not specify, either by your code or code called by your code, then the default behavior is to promptly terminate your program.
Also, I believe their use has been deprecated in current drafts of the C++0x standard.
A "throw()" specification allows the compiler to perform some optimisations when doing code flow analysis if it know that function will never throw an exception (or at least promises to never throw an exception). Larry Osterman talks about this briefly here:
http://blogs.msdn.com/larryosterman/archive/2006/03/22/558390.aspx
Generally I would not use exception specifiers. However, in cases where if any other exception were to come from the function in question that the program would definitively be unable to correct, then it can be useful. In all cases, make sure to document clearly what exceptions could be expected from that function.
Yes, the expected behavior of a non-specified exception being thrown from a function with exception specifiers is to call terminate().
I will also note that Scott Meyers addresses this subject in More Effective C++. His Effective C++ and More Effective C++ are highly recommended books.
They can be useful for unit testing so that when writing tests you know what to expect the function to throw when it fails, but there is no enforcement surrounding them in the compiler. I think that they are extra code that is not necessary in C++. Which ever you choose all that you should be sure of is that you follow the same coding standard across the project and the team members so that your code remains readable.
From the article:
http://www.boost.org/community/exception_safety.html
“It is well known to be impossible to
write an exception-safe generic
container.” This claim is often heard
with reference to an article by Tom
Cargill [4] in which he explores the
problem of exception-safety for a
generic stack template. In his
article, Cargill raises many useful
questions, but unfortunately fails to
present a solution to his problem.1 He
concludes by suggesting that a
solution may not be possible.
Unfortunately, his article was read by
many as “proof” of that speculation.
Since it was published there have been
many examples of exception-safe
generic components, among them the C++
standard library containers.
And indeed I can think of ways to make template classes exception safe. Unless you don't have control over all the sub-classes then you may have a problem anyway. To do this one could create typedefs in your classes that define the exceptions thrown by various template classes. This think the problem is as always tacking it on afterwards as opposed to designing it in from the start, and I think it's this overhead that's the real hurdle.
Exception specifications = rubbish, ask any Java developer over the age of 30