Is there any advantages or uses cases to throw other thing that a std::exception( or a derivatives types).
For example throw 1; or throw "error";
In other terms why the c++ standard allow it.
Per §15.1 [except]:
Exception handling provides a way of transferring control and
information from a point in the execution of a thread to an exception
handler associated with a point previously passed by the execution.
The word information illustrates everything, it can be everything such as objects, numbers, ... .
There is nothing in standard that says you must just throw std::exception. In the other words, maybe someone wants to throw his own exception objects.
Maybe someone wants to use exception-handling to handle something far from normal exceptions.
I can't think of any obvious reasons why a class derived from std::exception wouldn't typically be better.
But the throw 1 or throw "Error" are valid expressions, and they probably take a bit less "effort" creating, and there may be situations where this is a benefit. Throwing an exception type exception from the constructor of exception would probably not work very well, so there's one place.
However, it's probably more of a philosophical decision: Since throw can be made to throw a any type of object, it's not a bad idea to allow it. The more restrictions you put on things in a language, the more you restrict the possible uses of a language.
From reference material about std::exception:
std::exception
All objects thrown by components of the standard library are derived
from this class. Therefore, all standard exceptions can be caught by
catching this type by reference.
By throwing anything else, for example NuclearPlantException, you could handle your exceptions and the ones from the standard library separately. The standard library could throw std::invalid_argument or std::bad_alloc (subtypes of std::exception) and you could throw LossOfCoolant (a subtype of NuclearPlantException).
So there is at least one advantage: separating standard library exceptions from your exceptions. Because you don't throw std::bad_alloc if there's enough available space for your uranium, then any exception has a clear origin, potentially making testing and debugging easier.
Note: For more in-depth discussion see the question Should I inherit from std::exception?.
Yes, there can be advantages.
The most obvious is that the what for existing derivatives of std::exception (e.g., std::logic_error, std::invalid_argument) only deal with std::strings or char *s to specify the reason for the exception. That's probably fine if you only deal with an English speaking audience, but if you want to use the what to display an error message to somebody who doesn't use English, it can get clumsy in a hurry.
If you're using (for example) 32-bit Unicode strings throughout your program, you'd typically prefer do the same in your exception handling. In such a case, a hierarchy similar to those in the standard, but using 32-bit Unicode strings for the what argument probably makes a lot of sense. I suppose you could still use std::exception for the base of that hierarchy, but it's open to question how much (if anything) you'd gain from doing so.
Throwing things was in C++ a decade before std::exception or even std:: became an idea. This was not removed for backward compatibility reasons.
Those who chose not use std:: certainly like it that way, and throw other exceptions, likely derived from some base class supplied by a library. It's fine until you get several exception hierarchies to deal with in client code. So new code that does not fight against using std:: entirely (setting new_handler to avoid std::bad_alloc) is likely to re-fit its exception root classes to use std::exception as base.
Throwing non-class things like ints or pointers is often advised agaist, but in a light environment can make perfect sense -- in an small embedded project leaving the exceptions enabled but throwing only an enum sounds sensible.
In general, if the language allows to throw any copyable object why restrict it? While forcing to use a special library class would be not in spirit of C++ even if we had time travel.
Related
Is there any advantages or uses cases to throw other thing that a std::exception( or a derivatives types).
For example throw 1; or throw "error";
In other terms why the c++ standard allow it.
Per §15.1 [except]:
Exception handling provides a way of transferring control and
information from a point in the execution of a thread to an exception
handler associated with a point previously passed by the execution.
The word information illustrates everything, it can be everything such as objects, numbers, ... .
There is nothing in standard that says you must just throw std::exception. In the other words, maybe someone wants to throw his own exception objects.
Maybe someone wants to use exception-handling to handle something far from normal exceptions.
I can't think of any obvious reasons why a class derived from std::exception wouldn't typically be better.
But the throw 1 or throw "Error" are valid expressions, and they probably take a bit less "effort" creating, and there may be situations where this is a benefit. Throwing an exception type exception from the constructor of exception would probably not work very well, so there's one place.
However, it's probably more of a philosophical decision: Since throw can be made to throw a any type of object, it's not a bad idea to allow it. The more restrictions you put on things in a language, the more you restrict the possible uses of a language.
From reference material about std::exception:
std::exception
All objects thrown by components of the standard library are derived
from this class. Therefore, all standard exceptions can be caught by
catching this type by reference.
By throwing anything else, for example NuclearPlantException, you could handle your exceptions and the ones from the standard library separately. The standard library could throw std::invalid_argument or std::bad_alloc (subtypes of std::exception) and you could throw LossOfCoolant (a subtype of NuclearPlantException).
So there is at least one advantage: separating standard library exceptions from your exceptions. Because you don't throw std::bad_alloc if there's enough available space for your uranium, then any exception has a clear origin, potentially making testing and debugging easier.
Note: For more in-depth discussion see the question Should I inherit from std::exception?.
Yes, there can be advantages.
The most obvious is that the what for existing derivatives of std::exception (e.g., std::logic_error, std::invalid_argument) only deal with std::strings or char *s to specify the reason for the exception. That's probably fine if you only deal with an English speaking audience, but if you want to use the what to display an error message to somebody who doesn't use English, it can get clumsy in a hurry.
If you're using (for example) 32-bit Unicode strings throughout your program, you'd typically prefer do the same in your exception handling. In such a case, a hierarchy similar to those in the standard, but using 32-bit Unicode strings for the what argument probably makes a lot of sense. I suppose you could still use std::exception for the base of that hierarchy, but it's open to question how much (if anything) you'd gain from doing so.
Throwing things was in C++ a decade before std::exception or even std:: became an idea. This was not removed for backward compatibility reasons.
Those who chose not use std:: certainly like it that way, and throw other exceptions, likely derived from some base class supplied by a library. It's fine until you get several exception hierarchies to deal with in client code. So new code that does not fight against using std:: entirely (setting new_handler to avoid std::bad_alloc) is likely to re-fit its exception root classes to use std::exception as base.
Throwing non-class things like ints or pointers is often advised agaist, but in a light environment can make perfect sense -- in an small embedded project leaving the exceptions enabled but throwing only an enum sounds sensible.
In general, if the language allows to throw any copyable object why restrict it? While forcing to use a special library class would be not in spirit of C++ even if we had time travel.
Although this topic has been extensively discussed on SO, I'd like to clarify a few things that are still not clear to me so, considering the following facts:
10 years ago, Herb Sutter was telling us to refrain from using this functionality.
Specifying the possible exceptions that a function / method may throw does not force the compiler to yell at you when you decide to change the function's body and throw a new type of exception, forgetting by mistake to change the exception specification in the function's declaration.
If you have a very high level function that calls several other high level functions, which each run tons of code to produce the results, then I can imagine the maintenance from hell nightmare, when I would have to specify ALL the errors which the first function may throw, and this list would have to include all the exceptions the inner functions may throw and so on, thus creating tight coupling between high and low level functions, which is quite undesirable. On the other hand, we derive all exceptions from std::runtime_error, which we know is a good practice and we could specify that the high level functions just throw std::runtime_error and be done with it. But wait a minute... Where do we actually catch the exceptions? Would it not be rather odd / nasty / bad to enclose a call to one of these high level functions in a try / catch block, which catches a MyVerySpecific exception, when the high level function is supposed to throw only std::runtime_error??? Would it be any good to catch specific exceptions in lower level functions, which are not able to do anything about them but pass them on in a more generic container, with more information appended to them? I certainly don't want to write try / catch blocks in every function that I write, just to format exceptions. It would be like requiring every function to validate its parameters, and that can drive people insane, when they need to change something in a low level function.
Questions:
Do Herb Sutter's rants about exception specification still hold today? Has anything changed since then? I am mostly interested in pre-C++0x standards. If yes, I guess we can consider this topic closed.
Since it seems that the compiler mostly ignores these exception specifications, and when catching exceptions, in 99% of the cases, one would use catch (const CustomException &ex), how would one specify that a function throws CustomException? throw(CustomExecption) or throw (CustomException &) or throw (const CustomException &)? I have seen all variations, and, although I would go for the first one, do the others make any sense / add any benefits?
How would one actually use this functionality, and, at the same time, avoid the fallacies illustrated in the above 3rd fact?
EDIT: Suppose that we're building a library. How will its users know what exceptions to expect, if we don't use exception specification? They will certainly not see what functions will be called internally by the API methods...
1/ Do Herb Sutter's rants about exception specification still hold today? Has anything changed since then? I am mostly interested in pre-C++0x standards. If yes, I guess we can consider this topic closed.
Yes, they still hold.
Exceptions specifications are:
half-way implemented (function pointers don't specify exceptions, for example)
not checked at compile-time, but leading to termination at runtime !!
In general, I would be against exceptions specifications, because it causes a leak of implementation details. Look at the state of Java exceptions...
In C++ in particular ? Exceptions specifications are like shooting yourself in the foot since the tiniest error in documentation may lead to a std::terminate call. Note that almost all functions may throw a std::bad_alloc or a std::out_of_range for example.
Note: Since C++11, throw() was deprecated and now with C++17 it is gone; instead, from C++17 on, the noexcept(false) specifier can be used. It is better supported in function pointers, but still leads to termination at run-time rather than errors at compile-time.
2/ Since it seems that the compiler mostly ignores these exception specifications, and when catching exceptions, in 99% of the cases, one would use catch (const CustomException &ex), how would one specify that a function throws CustomException? throw(CustomExecption) or throw (CustomException &) or throw (const CustomException &)? I have seen all variations, and, although I would go for the first one, do the others make any sense / add any benefits?
The compiler does not ignore the exceptions specifications, it sets up very vigilant watchdogs (which axes) to make sure to kill your program in case you had missed something.
3/ How would one actually use this functionality, and, at the same time, avoid the fallacies illustrated in the above 3rd fact?
Your customer will appreciate if it stays informal, so the best example is:
void func(); // throw CustomException
and this lets you focus on the exceptions that matter too, and let "unimportant" exceptions slip through. If a consumer wants them all ? catch(std::exception const& e) works.
4/ EDIT: Suppose that we're building a library. How will its users know what exceptions to expect, if we don't use exception specification? They will certainly not see what functions will be called internally by the API methods...
Do they have to ?
Document what matters, std::exception or ... take care of the unexpected.
Do Herb Sutter's rants about exception specification still hold today? Has anything changed since then?
I wouldn't call that a rant. He just pointed out problems related to exception specifications.
Yes, it still holds. As explained in the text, if a not specified exception is throw, the program terminates, and that is not acceptable for 99% applications.
how would one specify that a function throws CustomException?
class A
{
//...
void foo() throws( CustomException );
};
How would one actually use this functionality, and, at the same time, avoid the fallacies illustrated in the above 3rd fact?
By looking at the function declaration, the user knows which exceptions can be thrown. The problem is when a new exception needs to be thrown, then all functions declarations needs to be changed.
Suppose that we're building a library. How will its users know what exceptions to expect, if we don't use exception specification?
By reading the documentation.
This might be kind of a silly question, but in C++, when I want to throw an exception.. what do I throw?
Am I supposed to throw std::exception, or is that reserved by the standard library? Or should I throw a string or int? Or should I just throw whatever I feel is appropriate?
Throw a class that's derived from std::exception; if you #include <stdexcept>, you can pick from a number of ready-made, useful derived classes.
Deriving from std::exception allows your handlers to follow a recognizable style, as you can always use .what() to get a textual message. Don't throw primitive types, since they carry no semantic information.
Generally people don't throw std::exception directly for the simple reason that it doesn't store any error messages. There wouldn't be anything for the what method to return. I get confused sometimes over this because MSVC provides a non-standard extension to this a parameterized constructor in std::exception that accepts a string.
You can choose among existing exception classes like std::runtime_exception or define your own. This is somewhat subjective but I recommend keeping the number of exception classes to a minimum as RAII can eliminate a lot of the need to have multiple code branches and catch blocks for different exception types. Often the message combined with RAII-conforming code is enough to gracefully recover from any exception.
And finally, I recommend all exceptions you throw inherit from std::exception for similar reasons. You don't want to have to litter your code with many different catch blocks for different exception types if you can avoid it. Solve the problem as generally as you can.
The primary exception to throwing something derived from std::exception would be if you're using some framework (e.g., MFC) with its own exception hierarchy. In that case, you generally want to derive from an appropriate spot in their hierarchy instead.
Note that I'm not particularly attempting to hold MFC up as an example of clean exception handling (or clean design in general), only an example of a framework that includes an exception hierarchy. When you're using a framework that already defines an exception hierarchy, you're generally better off using it.
In other words, unlike the preference in C++ otherwise, it's generally accepted that exceptions should be a single, monolithic hierarchy with a single root. For the standard library, that single root is std::exception, but other frameworks have alternatives, and if they provide one you generally want to fit yours into it.
Unlike java you CAN throw whatever (int, string, MyClass, ...) you want. But listen to Kerrek. :)
Usually you'll want to throw one of the exceptions derived from std::exception as others have said.
On occasion I've thrown other types, but only if it's caught within the same block and the value is something useful in that context.
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.
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