So I know that an exception class can inherit from the std exception library, but what exactly does an exception class do? It throws exceptions and handles them, but why should I use a class? Can an exception class handle more than 1 type of object?
There is no such thing as an "exception class" in C++; there are
no constraints with regards to the type of what you can throw
and catch. (throw 3.14159; is a perfectly legal C++
statement.) Good programming practice says that except in
special cases, you should throw objects which inherit from
std::exception, but this is not a requirement, and it's not
unusual for programs to throw an int to trigger the end of
program. (Calling exit doesn't invoke all of the destructors,
so the program throws an int, which is caught and returned in
main.)
Related
I have a class that is derived from another class. I want to be able to catch and re-throw the exception(s) thrown by the derived class's constructor in my derived class's constructor.
There seems to be a solution for this in C#:
https://stackoverflow.com/a/18795956/13147242
But since there is no such keyword as C#'s baseI have no idea how and if this is possible in C++.
Is there a solution? This would enable me to reuse quite a lot of code.
There is a pretty good example of this here: Exception is caught in a constructor try block, and handled, but still gets rethrown a second time
Ultimately, if you manage to catch an exception in the derived class the only thing you should do is to either rethrow that exception or throw a new one. This is because if the base class constructor does not complete then the derived class will be in an undefined state and you should not use it.
For a library code, is it better practice to create and throw custom exception class (library::Exception), or just throw standard exceptions (runtime_error, invalid_argument, etc.)?
It's usually better to specialize (inherit) a standard exception and throw it.
This way it'll be possible to catch it as a generic exception just by catching a std::exception, but you could also catch specifically your custom exception type if you need more specialized code.
Also see this C++Faq about what to throw.
Generally you should throw instances of classes in the stdexcept header or subclasses thereof. What class exactly makes sense depends on the specific problem. I think throwing instances of “category classes” std::logic_error and std::runtime_error is rarely useful since they carry no inherent meaning; they are used to distinguish the two main situations where exceptions can occur:
Subclasses of std::logic_error should be thrown by a function if it is called, but not all preconditions are fulfilled. The exception is the fault of the caller since it has failed to provide the necessary preconditions. For this category, you generally have to choose between throwing and undefined behavior; it is a trade-off between robustness and efficiently (e.g. std::vector::at() vs. std::vector::operator[]. These exceptions often cannot be handled; they are the result of bugs in the program.
Subclasses of std::runtime_error should be thrown by a function if all preconditions are met but the function cannot meet the postconditions or breaks invariants for reasons outside the control of the program (e.g., a file doesn’t exist, the network connection is lost, or not enough memory is available). These exceptions should usually be handled.
I think the available logic error classes (e.g. invalid_argument) are often good enough, because if they are raised, the code usually has to be fixed, and there is no reason for elaborate handling routines. On the other hand, the runtime error classes in the standard library are by their nature much less flexible and cover mainly the areas where the standard library itself has to throw exceptions. For your application, you should almost always inherit from these runtime error classes. For example, a class managing the operating system resource X should throw an X_creation_error which inherits from std::runtime_error if the constructor fails to allocate the resource.
Multiple virtual inheritance is often useful with exception classes. You can inherit from std::runtime_error or other stdexcept classes, from some “marker class” specific to your library, and from boost::exception to get the additional benefits of the Boost.Exception library. The Boost.Exception tutorial is highly recommended, especially Exception types as simple semantic tags and Using virtual inheritance in exception types.
IMHO Custom exception. The customers of your library will apreciate this. He will know whats exactly raises the exception.
From experience, it is rare that you need more than a very few exception classes.
In most of my code (mainly numerics -- if you do eg. IO, the situation is different), I throw standard exeptions (runtime_error, invalid_argument, ...) because they tend to indicate something that cannot be easily recovered from (except perhaps invalid_argument), and which will likely not be caught by user code (except perhaps at the top-level to throw a message box to the user).
If there is some exception which is intended to be caught by typical user code, eg. bad_custom_cast, or bad_market_data_identifier, instead of bubbling up to main (like a failure in a numerical routine, or bad_alloc), I make a custom class. But this is quite rare actually.
Once in a while, I notice some coding pattern that I've had for years and it makes me nervous. I don't have a specific problem, but I also don't remember enough about why I adopted that pattern, and some aspect of it seems to match some anti-pattern. This has recently happened to me WRT how some of my code uses exceptions.
The worrying thing involves cases where I catch an exception "by reference", treating it in a similar way to how I'd treat a parameter to a function. One reason to do this is so I can have an inheritance hierarchy of exception classes, and specify a more general or more precise catch type depending on the application. For example, I might define...
class widget_error {};
class widget_error_all_wibbly : public widget_error {};
class widget_error_all_wobbly : public widget_error {};
void wibbly_widget ()
{
throw widget_error_all_wibbly ();
}
void wobbly_widget ()
{
throw widget_error_all_wobbly ();
}
void call_unknown_widget (void (*p_widget) ())
{
try
{
p_widget ();
}
catch (const widget_error &p_exception)
{
// Catches either widget_error_all_wibbly or
// widget_error_all_wobbly, or a plain widget_error if that
// is ever thrown by anything.
}
}
This is now worrying me because I've noticed that a class instance is constructed (as part of the throw) within a function, but is referenced (via the p_Exception catch-clause "parameter") after that function has exited. This is normally an anti-pattern - a reference or pointer to a local variable or temporary created within a function, but passed out when the function exits, is normally a dangling reference/pointer since the local variable/temporary is destructed and the memory freed when the function exits.
Some quick tests suggest that the throw above is probably OK - the instance constructed in the throw clause isn't destructed when the function exits, but is destructed when the catch-clause that handles it completes - unless the catch block rethrows the exception, in which case the next catch block does this job.
My remaining nervousness is because a test run in one or two compilers is no proof of what the standard says, and since my experience says that what I think is common sense is often different to what the language guarantees.
So - is this pattern of handling exceptions (catching them using a reference type) safe? Or should I be doing something else, such as...
Catching (and explicitly deleting) pointers to heap-allocated instances instead of references to something that looks (when thrown) very like a temporary?
Using a smart pointer class?
Using "pass-by-value" catch clauses, and accepting that I cannot catch any exception class from a hierarchy with one catch clause?
Something I haven't thought of?
This is ok. It's actually good to catch exceptions by constant reference (and bad to catch pointers). Catching by value creates an unnecessary copy. The compiler is smart enough to handle the exception (and its destruction) properly -- just don't try to use the exception reference outside of your catch block ;-)
In fact, what I often do is to inherit my hierarchy from std::runtime_error (which inherits from std::exception). Then I can use .what(), and use even fewer catch blocks while handling more exceptions.
This pattern is definitely safe.
There are special rules that extend the lifetime of a thrown object. Effectively, it exists as long as it is being handled and it is guaranteed to exist until the end of the last catch block that handles it.
One very common idiom, for example, to derive custom exceptions from std::exception, override its what() member function, and catch it by reference so that you can print error messages from a wide variety of exceptions with one catch clause.
No, you're definitely doing it right. See http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.13 , and the rest of the FAQ chapter for that matter.
Yes. So far so good.
Personally I use std::runtime_error as the base of all exception calsses. It handles error messages etc.
Also don't declare more exceptions that you need to. Define an exception only for things that can actually be caught and fixed. Use a more generic exception for things that can not be caught or fixed.
For example: If I develop a library A. Then I will have an AException derived from std::runtime_error. This exception will be used for all generic exceptions from the library. For any specific exceptions where the user of the library can actually catch and do something (fix or mitigate) with the exception then I will create a specific exception derived from AException (but only if there is something that can be done with the exception).
Indeed, Sutter and Alexandrescu recomend this pattern in their 'C++ Coding Standards'.
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.
I have some special exception cases that I want to throw and catch, so I want to define my own exception classes.
What are the best practices for that? Should I inherit from std::exception or std::runtime_error?
Yes, it's good practice to inherit from std::runtime_error or the other standard exception classes like std::logic_error, std::invalid_argument and so on, depending on which kind of exception it is.
If all the exceptions inherit some way from std::exception it's easy to catch all common errors by a catch(const std::exception &e) {...}. If you have several independent hierarchies this gets more complicated. Deriving from the specialized exception classes makes these exceptions carry more information, but how useful this really is depends on how you do your exception handling.
I'm not a C++ developer, but one thing we did in our C# code was create a base class exception for our framework, and then log the exception thrown in the constructor:
public FrameworkException(string message, Exception innerException)
: base(message, innerException)
{
log.Error(message, innerException);
}
...
Any derived exception just has to invoke it's base constructor and we get consistent exception logging throughout. Not a big deal, but useful.
It is a good when exception is placed in some scope. For instance class Manipulation can declare inside exception classes Error.
and catch them like
catch ( const Manipulation::InputError& error )
catch ( const Manipulation::CalculationError& error )
In such cases they can be just empty classes without any additional error information unless you design allows those exceptions fly much upper where you catch all standard exceptions.
In my opinion it doesn't matter if you inherit from std::exception or not. For me the most important thing about defining exceptions are:
Having the exception class names be useful and clear.
Clearly documenting (writing comments) when exception will get thrown by a function or class method. This is the single biggest failure point in exception handling in my opinion.
It doesn't make a big difference, since std::runtime_error also inherits from std::exception. You could argue that runtime error conveys more information about the exception, but in practice, people often just derive from the base exception class.