So the way to nest exceptions in C++ using std::nested_exception is:
void foo() {
try {
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
catch(...) {
std::throw_with_nested(std::runtime_error("foo failed"));
}
}
But this technique uses explicit try/catch blocks at every level where one wishes to nest exceptions, which is ugly to say the least.
RAII, which Jon Kalb expands as "responsibility acquisition is initialization", is a much cleaner way to deal with exceptions instead of using explicit try/catch blocks. With RAII, explicit try/catch blocks are largely only used to ultimately handle an exception, e.g. in order to display an error message to the user.
Looking at the above code, it seems to me that entering foo() can be viewed as entailing a responsibility to report any exceptions as std::runtime_error("foo failed") and nest the details inside a nested_exception. If we can use RAII to acquire this responsibility the code looks much cleaner:
void foo() {
Throw_with_nested on_error("foo failed");
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
Is there any way to use RAII syntax here to replace explicit try/catch blocks?
To do this we need a type that, when its destructor is called, checks to see if the destructor call is due to an exception, nests that exception if so, and throws the new, nested exception so that unwinding continues normally. That might look like:
struct Throw_with_nested {
const char *msg;
Throw_with_nested(const char *error_message) : msg(error_message) {}
~Throw_with_nested() {
if (std::uncaught_exception()) {
std::throw_with_nested(std::runtime_error(msg));
}
}
};
However std::throw_with_nested() requires a 'currently handled exception' to be active, which means it doesn't work except inside the context of a catch block. So we'd need something like:
~Throw_with_nested() {
if (std::uncaught_exception()) {
try {
rethrow_uncaught_exception();
}
catch(...) {
std::throw_with_nested(std::runtime_error(msg));
}
}
}
Unfortunately as far as I'm aware, there's nothing like rethrow_uncaught_excpetion() defined in C++.
In the absence of a method to catch (and consume) the uncaught exception in the destructor, there is no way to rethrow an exception, nested or not, in the context of the destructor without std::terminate being called (when the exception is thrown in the context of exception handling).
std::current_exception (combined with std::rethrow_exception) will only return a pointer to a currently handled exception. This precludes its use from this scenario as the exception in this case is explicitly unhandled.
Given the above, the only answer to give is from an aesthetic perspective. Function level try blocks make this look slightly less ugly. (adjust for your style preference):
void foo() try {
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
}
catch(...) {
std::throw_with_nested(std::runtime_error("foo failed"));
}
It's impossible with RAII
Considering the simple rule
Destructors must never throw.
it is impossible with RAII to implement the thing you want. The rule has one simple reason: If a destructor throws an exception during stack unwinding due to an exception in flight, then terminate() is called and your application will be dead.
An alternative
In C++11 you can work with lambdas which can make life a little easier. You can write
void foo()
{
giveErrorContextOnFailure( "foo failed", [&]
{
// code that might throw
std::ifstream file("nonexistent.file");
file.exceptions(std::ios_base::failbit);
} );
}
if you implement the function giveErrorContextOnFailure in the following way:
template <typename F>
auto giveErrorContextOnFailure( const char * msg, F && f ) -> decltype(f())
{
try { return f(); }
catch { std::throw_with_nested(std::runtime_error(msg)); }
}
This has several advantages:
You encapsulate how the error is nested.
Changing the way errors are nested can be changed for the whole program, if this technique is followed strictly program wide.
The error message can be written before the code just as in RAII. This technique can be used for nested scopes as well.
There's less code repetition: You don't have to write try, catch, std::throw_with_nested and std::runtime_error. This makes your code more easily maintainable. If you want to change the behavior of your program you need to change your code in one place only.
The return type will be deduced automatically. So if your function foo() should return something, then you just add return before giveErrorContextOnFailure in your function foo().
In release mode there will typically be no performance panelty compared to the try-catch-way of doing things, since templates are inlined by default.
One more interesting rule to follow:
Do not use std::uncaught_exception().
There's a nice article about this topic by Herb Sutter which explains this rule perfectly. In short: If you have a function f() which is called from within a destructor during stack unwinding looking like this
void f()
{
RAII r;
bla();
}
where the destructor of RAII looks like
RAII::~RAII()
{
if ( std::uncaught_exception() )
{
// ...
}
else
{
// ...
}
}
then the first branch in the destructor will always be taken, since in the outer destructor during stack unwinding std::uncaught_exception() will always return true, even inside functions called from that destructor including the destructor of RAII.
Related
I have an API which internally has some exceptions for error reporting. The basic structure is that it has a root exception object which inherits from std::exception, then it will throw some subclass of that.
Since catching an exception thrown in one library or thread and catching it in another can lead to undefined behavior (at least Qt complains about it and disallows it in many contexts). I would like to wrap the library calls in functions which will return a status code, and if an exception occurred, a copy of the exception object.
What is the best way to store an exception (with it's polymorphic behavior) for later use? I believe that the c++0x future API makes use of something like this. So what is the best approach?
The best I can think of is to have a clone() method in each exception class which will return a pointer to an exception of the same type. But that's not very generic and doesn't deal with standard exceptions at all.
Any thoughts?
EDIT: It seems that c++0x will have a mechanism for this. It is described as "library magic". Does that mean that is doesn't require any of the language features of c++0x? if not, are there any implementations which are compatible with c++03?
EDIT: Looks like boost has an implementation of exception copying. I'll keep the question open for any non boost::copy_exception answers.
EDIT: To address j_random_hacker's concerns about the root cause of the exception being an out of memory error. For this particular library and set of exceptions, this is not the case. All exceptions derived from the root exception object represent different types of parsing errors caused by invalid user input. Memory related exceptions will simply cause a std::bad_alloc to be thrown which is addressed separately.
As of C++11, this can be done using std::exception_ptr.
(I use this in a class that makes an std::thread interruptible provided that the underlying thread implementation is a POSIX thread. To handle exceptions that may be thrown in the user's code - which causes problems if they are thrown in a certain critical section of my implementation - I store the exception using std::exception_ptr, then throw it later once the critical section has completed.)
To store the exception, you catch it and store it in the ptr variable.
std::exception_ptr eptr;
try {
... do whatever ...
} catch (...) {
eptr = std::current_exception();
}
You can then pass eptr around wherever you like, even into other threads (according to the docs - I haven't tried that myself). When it is time to use (i.e. throw) it again, you would do the following:
if (eptr) {
std::rethrow_exception(eptr);
}
If you want to examine the exception, you would simply catch it.
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch (const std::exception& e) {
... examine e ...
} catch (...) {
... handle any non-standard exceptions ...
}
You have what would be what I think is your best, only answer. You can't keep a reference to the original exception because it's going to leave scope. You simply have to make a copy of it and the only generic way to do that is with a prototype function like clone().
Sorry.
You're allowed to throw anything, including pointers. You could always do something like this:
throw new MyException(args);
And then in the exception handler store the caught pointer, which will be fully polymorphic (below assuming that MyException derives from std::exception):
try {
doSomething(); // Might throw MyException*
} catch (std::exception* pEx) {
// store pEx pointer
}
You just have to be careful about memory leaks when you do it this way, which is why throw-by-value and catch-by-reference is normally used.
More about catch-by-pointer: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
The reason why catching an exception thrown in one library and catching it in another can lead to undefined behavior is that these libraries could be linked with different Runtime libraries. If you will return exception from a function instead of throwing it you will not avoid that problem.
My utility library has an AnyException class that is basically the same as boost::any without the casting support. Instead, it has a Throw() member that throws the original object stored.
struct AnyException {
template<typename E>
AnyException(const E& e)
: instance(new Exception<E>(e))
{ }
void Throw() const {
instance->Throw();
}
private:
struct ExceptionBase {
virtual void Throw() const =0;
virtual ~ExceptionBase() { }
};
template<typename E>
struct Exception : ExceptionBase {
Exception(const E& e)
: instance(e)
{ }
void Throw() const {
throw std::move(instance);
}
private:
E instance;
};
ExceptionBase* instance;
};
This is a simplification, but that's the basic framework. My actual code disables copying, and has move semantics instead. If needed, you can add a virtual Clone method to the ExceptionBase easily enough... since Exception knows the original type of the object, it can forward the request onto the actual copy constructor, and you immediately have support for all copiable types, not just ones with their own Clone method.
When this was designed, it was not meant for storing caught exceptions... once an exception was thrown, it propagated as normal, so out-of-memory conditions were not considered. However, I imagine you could add an instance of std::bad_alloc to the object, and store it directly in those situations.
struct AnyException {
template<typename E>
AnyException(const E& e) {
try {
instance.excep = new Exception<E>(e);
has_exception = true;
} catch(std::bad_alloc& bad) {
instance.bad_alloc = bad;
bas_exception = false;
}
}
//for the case where we are given a bad_alloc to begin with... no point in even trying
AnyException(const std::bad_alloc& bad) {
instance.bad_alloc = bad;
has_exception = false;
}
void Throw() const {
if(has_exception)
instance.excep->Throw();
throw instance.bad_alloc;
}
private:
union {
ExceptionBase* excep;
std::bad_alloc bad_alloc;
} instance;
bool has_exception;
};
I haven't actually tested that second bit at all... I might be missing something glaringly obvious that will prevent it from working.
When a function throws while the exception is uncaught, stack unwinding is unlikely to trigger, so destructors of local variables won't be called. For example, the following code outputs only "created" (and the error messages) under g++ 7.1.0:
#include <iostream>
using namespace std;
struct A {
A() { cerr << "created\n"; }
~A() { cerr << "destroyed\n"; }
};
void f() {
A a;
throw 0;
}
int main() {
f();
}
This may lead to memory leaks upon crashing if A allocates memory, and whether the memory will be freed depends on the OS.
A possible solution I find is wrap f() in a function try-catch block:
void f() try {
A a;
throw 0;
} catch (...) {
throw;
}
In this way destructor of a is always called. However, I don't find it satisfying because an empty catch clause has to be written, and it's not straightforward.
So which of the following should be considered correct, or if there's better practice (especially when implementing a function in a library) ?
Wrap every potentially-throwing function with try-catch block mentioned above;
Pretend the callers to this function always catches the exception;
Because uncaught exception causes crashing, I don't have to destruct local variables.
Put a top-level try-catch(...) in your main function that outputs an error message and exits. This will ensure that unwinding always happens.
Though the question is why you would want that. If you're in any real-world non-embedded environment, the OS will clean up all resources of your process. There's no maybe about it. And since there are other ways for a process to crash which don't involve exceptions, you can't rely on destructors for cleanup in such a case anyway.
If you're in an embedded environment, the situation is similar. You don't have an OS to clean up, maybe, but crashes usually lead to a device reset, which has the same effect. And again, you can't rely on destructors because there are other ways to crash.
Ive got a short bit of code that is giving me the following the warning upon compilation:
'BGOLUB::Containers::Stack::Pop' : not all control paths return a value
Here is the code:
template<typename T>
T Stack<T>::Pop()
{
try
{
if (m_index<0) throw OutOfBoundsException(m_index);
--m_index;
return(m_array[m_index]);
}
catch(OutOfBoundsException&)
{
cerr<<"Underflow Index = "<<m_index<<endl;
}
catch(...)
{
cerr<<"Unhandled Error Occured"<<endl;
}
}
Any advice?
Many thanks!
Any advice?
The compiler is giving you the best advice. Not all the control paths in your function contain a return statement, and your function is supposed to return a value.
If an exception is thrown and control is transferred to a catch handler, that handler will print something to cerr and then flow off the end of your function without actually returning anything.
This is Undefined Behavior. Per Paragraph 6.6.3/2 of the C++11 Standard:
[..] Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
For default-constructible values, you could fix this by adding a return T() statement right before the end of your function:
template<typename T>
T Stack<T>::Pop()
{
try
{
// ...
}
catch (OutOfBoundsException&)
{
// ...
}
catch (...)
{
// ...
}
return T();
// ^^^^^^^^^^^
}
A more reasonable approach is, however, to not have Pop() swallow the exception, but rather re-throw it. Pop() does not have strategic-level information on how to recover from an error occurred in this context:
template<typename T>
T Stack<T>::Pop()
{
try
{
// ...
}
catch (OutOfBoundsException&)
{
// ...
throw; // <== Re-throw after printing the diagnostic
}
catch (...)
{
// ...
throw; // <== Re-throw after printing the diagnostic
}
}
Even better would be if the responsibility for logging an error message did not belong to Pop() at all, since Pop() is likely supposed to be re-used by code with different requirements in this sense (some may not want to log anything, some may want to log messages to a file, some may want to log messages in a different language, and so on).
So a more reasonable version of your function would actually be:
template<typename T>
T Stack<T>::Pop()
{
if (m_index<0) throw OutOfBoundsException(m_index);
--m_index;
return(m_array[m_index]);
}
In general, you should try (no pun intended) to avoid try/catch blocks unless you have to:
Translate an exception
Recover from the error (but you need strategic knowledge for doing this)
If this not your task (as is the case for a function like Pop() above), in most situations the best thing to do is to not handle exceptions at all and let them propagate up the call stack.
To quote Dave Abrahams:
Often the best way to deal with exceptions is to not handle them at all. If you can let them pass through your code and allow destructors to handle cleanup, your code will be cleaner.
To avoid leaking memory, resources, or in general responsibilities, write code that is exception-safe by using adequate RAII wrappers. Excellent guidelines in this sense are given in this two-part talk by Jon Kalb.
In particular, avoid writing catch (...) handlers: exceptions were invented to prevent programmers from ignoring errors, and swallowing them all in a universal handler without re-throwing them is the best way to ignore them.
NOTE:
Notice, that your implementation of Pop() is a bit problematic: what happens if the copy constructor or move constructor of T throws when returning the element back to the caller, after you already modified the stack pointer?
This is the reason why the C++ Standard Library defines two separate functions pop() and top(): because it allows to offer strong guarantee, i.e. to give transactional semantics to your pop() operation - either the element is removed without exceptions being thrown, or the function had no effect at all.
You need either rethrow exceptions, or return something probably T() at the end of function.
When the exception is thrown, it will be caught by one of the two catch statements. However, they still need to return a value from the function. You could place a return statement right at the end of your function.
However, if Pop throws an exception because the Stack is empty, it makes much more sense for it to let the exception propagate out of the function. Why is Pop itself attempting to handle the exceptional situation?
I would recommend using brackets with all of your if statements, even with one-line bodies. They are not strictly necessary, and you can write perfectly legal code without them, but they make your code much more readable, and errors such as this will be much easier to find.
Additionally, it seems you have a fundamental misunderstanding of how exceptions work. If your code were to encounter an exception, it would jump straight to the catch block, and not execute any subsequent code in the try block. Therefore, the return statement in you try block will never be reached, and your function will not return anything, since the catch blocks lack return statements.
You can resolve this issue by adding a return statement in your catch block.
I know this is a valid c++ program.
What is the point of the throw in the function declarement? AFAIK it does nothing and isnt used for anything.
#include <exception>
void func() throw(std::exception) { }
int main() { return 0; }
It specifies that any std::exception can be thrown from func(), and nothing else. If something else is thrown, it will call an unexpected() function which by default calls terminate().
What this means is that throwing something else will almost certainly terminate the program, in the same manner as an uncaught exception, but the implementation will have to enforce this. This is normally much the same as putting a try{...}catch(){...} block around func(), which can inhibit performance.
Usually, exception specifications aren't worth it, according to the Guru of the Week column about it. The Boost guidelines say that there might be a slight benefit with a blank throws() for a non-inline function, and there are disadvantages.
That is an exception specification, and it is almost certainly a bad idea.
It states that func may throw a std::exception, and any other exception that func emits will result in a call to unexpected().
This is a C++ exception specification. It declares that the particular function will potentially throw a std::exception type.
In general though exception specifications in C++ are considered a feature to avoid. It's an odd feature in that it's behavior is declared at compile time but only checked at runtime (very different from say Java's version).
Here is a good article which breaks down the feature
http://www.gotw.ca/publications/mill22.htm
This is an exception specification. It says that the only exception that func() can throw is std::exception (or a derivative thereof). Attempting to throw any other exception will give std::unexpected instead.
Exception specification. The type(s) following the throw keyword specifies exactly what all, if any, exceptions the function can throw. See 15.4 of the draft.
Note: A function with no exception-specification allows all exceptions. A function with an empty exception-specification, throw(), does not allow any exceptions.
Basically this:
void func() throw(std::exception,B) { /* Do Stuff */}
Is just shorthand fro this:
void func()
{
try
{
/* Do Stuff */
}
catch(std::exception const& e)
{
throw;
}
catch(B const& e)
{
throw;
}
catch(...)
{
unexpected(); // This calls terminate
// i.e. It never returns.
}
}
Calling terminate() is rarely what you want, as the stack is not unwound and thus all your efforts in RAII is wasted. The only exception to the rule is declaring an empty throw list and this is mainly for documentation purposes to show that you are supporting the no-throw exception gurantee (you should still manually catch all exceptions in this situation).
Some important (imho) places that should be no-throw are destructors and swap() methods. Destructors are rarely explicitly marked no-throw but swap() are quite often marked no-throw.
void myNoThrowFunc() throws() // No-Throw (Mainlly for doc purposes).
{
try
{
/* Do Stuff */
}
catch(...) // Make sure it does not throw.
{
/* Log and/or do cleanup */
}
}
Note that this function does not have a "{" and "}" body. Just a try/catch block:
void func( void )
try
{
...
}
catch(...)
{
...
}
Is this intentionally part of C++, or is this a g++ extension?
Is there any purpose to this other than bypass 1 level of {}?
I'd never heard of this until I ran into http://stupefydeveloper.blogspot.com/2008/10/c-function-try-catch-block.html
Yes, that is valid C++. One purpose i've found for it is to translate exceptions into return values, and have the code translating the exceptions in return values separate from the other code in the function. Yes, you can return x; from a catch block like the one you showed (i've only recently discovered that, actually). But i would probably just use another level of braces and put the try/catch inside the function in that case. It will be more familiar to most C++ programmers.
Another purpose is to catch exceptions thrown by an constructor initializer list, which uses a similar syntax:
struct f {
g member;
f() try {
// empty
} catch(...) {
std::cerr << "thrown from constructor of g";
}
};
Yes, it is standard. Function try blocks, as they're called, aren't that much use for regular functions, but for constructors, they allow you to catch exceptions thrown in the initialiser list.
Note that, in the constructor case, the exception will always be rethrown at the end of any catch blocks.