Should Lippincott functions be declared noexcept? - c++

EDIT: Another way to ask this question, in perspective, is to ask: Should Lippincott functions "catch all"?
Should Lippincott functions be declared noexcept?, does it matter?
After all, a version of this function in which all exceptions are captured, by definition cannot produce an exception.
However, in all the examples I see online, the noexcept is never there and I was wondering if I was missing something.
Example case:
foo_Result lippincott() noexcept???
{
try {
throw;
} catch (const MyException1&) {
return FOO_ERROR1;
} catch (const MyException2&) {
return FOO_ERROR2;
} catch (...) {
return FOO_UNKNOWN;
}
}
foo_Result foo_dothing() {
try {
foo::DoThing();
return FOO_OK;
}
catch (...) {
return lippincott();
}
}

Not all catch (...) executions come from a C++ exception. It is typically advisable to rethrow the exception in any catch-all block. This would imply that lippincott should not be noexcept and also just not have the catch-all block.
Specifically, in the ABI commonly used for C++ outside of Windows, forced unwinding may execute catch-all blocks:
A catch-all block may be executed during forced unwinding. For
instance, a longjmp may execute code in a catch(...) during stack
unwinding. However, if this happens, unwinding will proceed at the end
of the catch-all block, whether or not there is an explicit rethrow.
In particular, with GCC on Linux, the blocks are executed, and if not rethrown, the application is terminated. Forced unwinding can happen even in code you completely control on POSIX if you ever call cancellation points (e.g. read).
Aside from this, it's not uncommon for a library to execute user code (e.g. think qsort). You also usually don't want to suppress those exceptions.
Therefore, the best generic option is to be transparent in catch-all blocks. Perform the cleanup you need. Then always rethrow.
So your function would look something like:
foo_Result lippincott()
{
try {
throw;
} catch (const MyException1&) {
return FOO_ERROR1;
} catch (const MyException2&) {
return FOO_ERROR2;
} catch (const FooBaseException&) {
return FOO_UNKNOWN;
}
}
GCC does allow catching forced unwinds, so if you really wanted a catch-all and the other consideration is discarded (e.g. no user callbacks), you can first catch abi::__forced_unwind and rethrow.

Related

Properly terminating program. Using exceptions

Question:
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)? Or can I just explicitly call something like exit(EXIT_FAILURE) instead?
What I'm Currently Doing:
I'm working on a game project and am trying to figure out the best way to terminate the program in the case of an error that calls for such an action. For example, in the case the textures can't be loaded I display an error message and terminate the program.
I'm currently doing this with exceptions like so:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
return 0;
}
All but bad_alloc are my own defined exceptions derived from runtime_error.
I don't need any manual resource cleanup and I'm using std::unique_ptr for any dynamic allocation. I just need to display the error message and close the program.
Research/Alternatives to Exceptions:
I've looked up a lot of posts on SO and other places and have seen others say anything from don't use exceptions, to use exceptions but your using them wrong. I've also looked up explicitly calling something like exit().
Using exit() sounds nice but I read it won't go back through the call stack up to main cleaning everything up (if I can find this again I'll post the link). Additionally, according to http://www.cplusplus.com/reference/cstdlib/exit/ this should not be used if multiple threads are active. I do expect to be creating a second thread for a short time at least once, and an error could occur in that thread.
Not using exceptions was mentioned in some replies here in relation to games https://gamedev.stackexchange.com/questions/103285/how-industy-games-handle-their-code-errors-and-exceptions
Use exceptions was discussed here: http://www.quora.com/Why-do-some-people-recommend-not-using-exception-handling-in-C++
There are a number of other sources I've read but those were the most recent I looked at.
Personal Conclusion:
Due to my limited experience of working with error handling and using exceptions, I'm not sure if I'm on the right track. I've chosen the route of using exceptions based on the code I posted above. If you agree that I should tackle those cases with exceptions, am I using it correctly?
It's generally considered good practice to let all exceptions propagate through to main. This is primarily because you can be sure the stack is properly unwound and all destructors are called (see this answer). I also think it's more organised to do things this way; you always known where your program will terminate (unless the program crashes). It's also facilitates more consistent error reporting (a point often neglected in exception handling; if you can't handle the exception, you should make sure your user knows exactly why). If you always start with this basic layout
int main(int argc, const char **argv)
{
try {
// do stuff
return EXIT_SUCCESS;
} catch (...) {
std::cerr << "Error: unknown exception" << std::endl;
return EXIT_FAILURE;
}
}
then you won't go far wrong. You can (and should) add specific catch statements for better error reporting.
Exceptions when multithreading
There are two basic ways of executing code asynchronously in C++11 using standard library features: std::async and std::thread.
First the simple one. std::async will return a std::future which will capture and store any uncaught exceptions thrown in the given function. Calling std::future::get on the future will cause any exceptions to propagate into the calling thread.
auto fut = std::async(std::launch::async, [] () { throw std::runtime_error {"oh dear"}; });
fut.get(); // fine, throws exception
On the other hand, if an exception in a std::thread object is uncaught then std::terminate will be called:
try {
std::thread t {[] () { throw std::runtime_error {"oh dear"};}};
t.join();
} catch(...) {
// only get here if std::thread constructor throws
}
One solution to this could be to pass a std::exception_ptr into the std::thread object which it can pass the exception to:
void foo(std::exception_ptr& eptr)
{
try {
throw std::runtime_error {"oh dear"};
} catch (...) {
eptr = std::current_exception();
}
}
void bar()
{
std::exception_ptr eptr {};
std::thread t {foo, std::ref(eptr)};
try {
// do stuff
} catch(...) {
t.join(); // t may also have thrown
throw;
}
t.join();
if (eptr) {
std::rethrow_exception(eptr);
}
}
Although a better way is to use std::package_task:
void foo()
{
throw std::runtime_error {"oh dear"};
}
void bar()
{
std::packaged_task<void()> task {foo};
auto fut = task.get_future();
std::thread t {std::move(task)};
t.join();
auto result = fut.get(); // throws here
}
But unless you have good reason to use std::thread, prefer std::async.
There's nothing wrong with catching unrecoverable errors and shutting down your program this way. In fact, it's how exceptions should be used. However, be careful not to cross the line of using exceptions to control the flow of your program in ordinary circumstances. They should always represent an error which cannot be gracefully handled at the level the error occurred.
Calling exit() would not unwind the stack from wherever you called it. If you want to exit cleanly, what you're already doing is ideal.
You have already accepted an answer, but I wanted to add something about this:
Can I just explicitly call something like exit() instead?
You can call exit, but (probably) shouldn't.
std::exit should be reserved for situations where you want to express "exit right now!", not simply "application has nothing left to do".
As an example, if you were to write a controller for a laser used in cancer treatments, your first priority in case something went wrong would be to shut down the laser and call std::exit - or possibly std::terminate (to ensure any side effects of a hanging, slow or crashing application do not kill a patient).
Similar to how exceptions should not be used for controlling application flow, exit should not be used to stop the application in normal conditions.
Is using exceptions the proper way to terminate my program if all I want is to display an error message and close (accounting that I may be deep in the program)?
Yes. This is the reason for using exceptions. An error occurred deep down in the code and something at a higher level will handle it. In your case, at the highest level.
There are arguments for/against exceptions vs. error codes, and this is a good read:
Exceptions or error codes
Can I just explicitly call something like exit() instead?
You can, but you may end up duplicating your logging code. Also, if in the future you decide that you want to handle an exception differently you will have to change all your exit calls. Imagine you wanted a different message, or to fall back on an alternative process.
Another similar question:
Correct usage of exit() in c++?
You also have a flaw in your approach as you don't handle all (C++) exceptions. You want something like this:
int main()
{
Game game;
try
{
game.run();
}
catch (BadResolutionException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Resolution");
return 1;
}
catch (BadAssetException & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Assets");
return 1;
}
catch (std::bad_alloc & e)
{
Notification::showErrorMessage(e.what(), "ERROR: Memory");
return 1;
}
catch (...)
{
// overload?
Notification::showErrorMessage("ERROR: Unhandled");
return 1;
}
return 0;
}
If you don't handle all* exceptions you could have the game terminate without telling you anything useful.
You can't handle ALL exceptions. See this link:
C++ catching all exceptions
From the documentation:
[[noreturn]] void exit (int status);
Terminate calling process
Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
Objects with static storage duration are destroyed (C++) and functions registered with atexit are called.
All C streams (open with functions in ) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
Control is returned to the host environment.
Note that objects with automatic storage are not destroyed by calling exit (C++).
If status is zero or EXIT_SUCCESS, a successful termination status is returned to the host environment.
If status is EXIT_FAILURE, an unsuccessful termination status is returned to the host environment.
Otherwise, the status returned depends on the system and library implementation.
For a similar function that does not perform the cleanup described above, see quick_exit.

c++ exception handling

Learning "try & catch". What is wrong with the following code?
Thanks for the advice.
Error in execution:
terminate called without an active exception
Aborted
The code:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw;
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
Your throw; statement tries to rethrow a current exception but there probably isn't one. You need something like
throw some_exception_object();
Inside of a try block, you have to specify what to throw. The only place you can use throw by itself is inside of a catch block to re-throw the current exception. If you call throw by itself without a current exception being active, you will kill your app, as you have already discovered.
Try this:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw 1; // throws an int
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
You can throw anything you want, as long as you throw something.
There are four things, two major and two minor. One thing at a time...
1. Rethrow usage w/o active exception
A throw; statement is used to re-throw an exception that is currently caught. For example:
try {
do_something();
} catch (const std::exception &) {
throw; // This statement re-throws an exception that was caught in this "catch" block.
}
In your case, you are using throw; without catching any exceptions (in order words — it does not appear inside catch block directly or indirectly), thus your program is terminated. When there is a need to throw and not to re-throw an exception, like in your case, you must specify an exception object to be thrown. For example:
throw std::runtime_error("Something bad happened");
2. catch-all clause which does not re-throw a caught exception
Your catch-all clause (catch (...)) is perfectly legal C++. However, it does not re-throw caught exception. Even though it is a legal C++ code, such a usage is a taboo. C and C++ runtime is usually using special types of exceptions to implement certain functionality. For example, NPTL is using exceptions to implement a thread cancellation. If you catch that exception using catch (...), a thread won't be cancelled and you are going to have a bad time. Generally, you have to catch exceptions by their types. In almost all cases, exceptions are inherited from std::exception, and so you have to write catch (const std::exception &) or, if you expect to catch an exact type, - catch(const TypeYouExpect &). If you must, however, use catch-all, remember to re-throw. For example:
try {
do_something();
} catch (...) {
throw; // DO NOT FORGET TO RE-THROW.
}
3. Header naming...
You are including C header whereas C++ provides its own headers for standard C features. So, header:
#include <stdio.h>
.. should be:
#include <cstdio>
C++ specific C functions get special treatment. For example, they become available in std namespace. So that you can use std::open() instead of just open() or ::open(). No big deal, but is highly recommended way to go.
4. Return from main.
Unlike C, C++'s main() function is very special. It allows you not to have return 0;. This is a default behavior. So, unless you really need to return some value, you may save yourself some time by not typing return 0;. Remember, however, that main is the only function like that, and that everywhere else you must explicitly return something unless a function is marked void.
Hope it helps. Good Luck!
You need to actually throw some object. Even something as simple as
throw "error";
will catch the error like you want it to.
see it in action here
The statement to throw an exception is:
throw <expression>;
This statement:
throw;
is also called the re-throw statement and is use to re-throw an existing exception that has been caught. It is typically used in a catch block, for example, you look at the exception and decide if you can continue, retry or abort. In case you decide to abort, you re-throw the exception so that somebody else down the call stack will catch it and handle this error.
For example:
// getResult() calls can fail with a deadlock exception
// This method will retry up to 3 times before failing
Result getResultWithRetry()
{
int nbTry = 3;
for(;;) {
try {
return getResult();
} catch (DeadLockException& e) {
if (nbTry == 0) {
throw; // re-throw the deadlock exception
}
}
--nbTry;
}
}

what does "throw;" outside a catch block do?

I just stumbled this code:
void somefunction()
{
throw;
}
and I wonder: what does it mean?
The intent is probably that somefunction() is only ever called from inside some catch block. In that case, there would be an exception active when the throw; is executed, in which case the current exception is re-thrown, to be caught by the next outer handler that can handle that exception type.
If throw; is executed when an exception is not active, it calls terminate() (N4810, §[expr.throw]/4).
It re-throws the currently active exception. It would only make sense to call it (possibly indirectly) from a catch-block. This:
#include <iostream>
using namespace std;
void f() {
throw;
}
int main() {
try {
try {
throw "foo";
}
catch( ... ) {
f();
}
}
catch( const char * s ) {
cout << s << endl;
}
}
prints "foo".
For throw the concept of being "outside" or "inside" catch block is defined in run-time terms, not in compile-time terms as you seem to assume. So, if during run-time that throw is executed in run-time context of a catch block, then throw works as expected. Otherwise, terminate() is called.
In fact, if you take a closer look at how C++ exceptions are defined in the language specification, a lot of things about them are defined in run-time terms. Sometimes it even appears to be un-C++-like.
People have already explained what it means but it's potentially useful to know why you might see it. It's a useful way to construct a 'generic' exception handler that deals with exceptions based on their type so as to reduce the amount of duplicated code.
So, if we take Neil's example and expand on what f() might be doing we might end up with an implementation which does something like my LogKnownException() function that I proposed in this answer.
If you are working in an team that likes to log all manner of exceptions all over the place then rather than having a huge collection of catch blocks at all of these places (or even worse a macro) you can have a simple catch block that looks like this
catch(...)
{
LogKnownException();
}
Though I expect I'd change my previous example of LogKnownException() to one that simply allowed exceptions that it didn't want to log to propagate out and continue on in an unhandled fashion.
I'm not suggesting that this is necessarily a good thing to do, just pointing out that this is where you're likely to see the construct used.

What happens if I use "throw;" without an exception to throw?

Here's the setup.
I have a C++ program which calls several functions, all of which potentially throw the same exception set, and I want the same behaviour for the exceptions in each function
(e.g. print error message & reset all the data to the default for exceptionA; simply print for exceptionB; shut-down cleanly for all other exceptions).
It seems like I should be able to set the catch behaviour to call a private function which simply rethrows the error, and performs the catches, like so:
void aFunction()
{
try{ /* do some stuff that might throw */ }
catch(...){handle();}
}
void bFunction()
{
try{ /* do some stuff that might throw */ }
catch(...){handle();}
}
void handle()
{
try{throw;}
catch(anException)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
catch(anotherException)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
catch(...)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
}
Now, what happens if "handle" is called outside of the exception class.
I'm aware that this should never happen, but I'm wondering if the behaviour is undefined by the C++ standard.
If handle() is called outside the context of an exception, you will throw without an exception being handled. In this case, the standard (see section 15.5.1) specifies that
If no exception is presently being handled, executing a throw-expression with no operand calls terminate().
so your application will terminate. That's probably not what you want here.
If you use throw inside of a catch block, it will rethrow the exception. If you use throw outside of a catch block, it will terminate the application.
Never, never, never use catch(...) as you might catch application errors that you don't want to catch, e.g. bugs, access violations (depending on how you compiled).
Read the great John Robbins book (Debugging Windows Applications) in which he explains more in detail why you shouldn't do it.

How can I catch all types of exceptions in one catch block?

In C++, I'm trying to catch all types of exceptions in one catch (like catch(Exception) in C#). How is it done? And what's more, how can one catch divide-by-zero exceptions?
catch (...)
{
// Handle exceptions not covered.
}
Important considerations:
A better approach is to catch specific types of exception that you can actually recover from as opposed to all possible exceptions.
catch(...) will also catch certain serious system level exceptions (varies depending on compiler) that you are not going to be able to recover reliably from. Catching them in this way and then swallowing them and continuing could cause further serious problems in your program.
Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown. In this case, you log all useful local state information and then re-throw the exception to allow it to propagate up. However you should read up on the RAII pattern if you choose this route.
You don't want to be using catch (...) (i.e. catch with the ellipsis) unless you really, definitely, most provable have a need for it.
The reason for this is that some compilers (Visual C++ 6 to name the most common) also turn errors like segmentation faults and other really bad conditions into exceptions that you can gladly handle using catch (...). This is very bad, because you don't see the crashes anymore.
And technically, yes, you can also catch division by zero (you'll have to "StackOverflow" for that), but you really should be avoiding making such divisions in the first place.
Instead, do the following:
If you actually know what kind of exception(s) to expect, catch those types and no more, and
If you need to throw exceptions yourself, and need to catch all the exceptions you will throw, make these exceptions derive from std::exception (as Adam Pierce suggested) and catch that.
If you are on windows and need to handle errors like divide by zero and access violation you can use a structured exception translator. And then inside of your translator you can throw a c++ exception:
void myTranslator(unsigned code, EXCEPTION_POINTERS*)
{
throw std::exception(<appropriate string here>);
}
_set_se_translator(myTranslator);
Note, the code will tell you what the error was. Also you need to compile with the /EHa option (C/C++ -> Code Generatrion -> Enable C/C++ Exceptions = Yes with SEH Exceptions).
If that doesn't make sense checkout the docs for [_set_se_translator](http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)
If catching all exceptions - including OS ones - is really what you need, you need to take a look at your compiler and OS. For example, on Windows you probably have "__try" keyword or compiler switch to make "try/catch" catch SEH exceptions, or both.
Make all your custom exception classes inherit from std::exception, then you can simply catch std::exception. Here is some example code:
class WidgetError
: public std::exception
{
public:
WidgetError()
{ }
virtual ~WidgetError() throw()
{ }
virtual const char *what() const throw()
{
return "You got you a widget error!";
}
};
In C++, the standard does not define a divide-by-zero exception, and implementations tend to not throw them.
You can, of course, use catch (...) { /* code here */ }, but it really Depends On What You Want To Do. In C++ you have deterministic destructors (none of that finalisation rubbish), so if you want to mop up, the correct thing to do is to use RAII.
For example. instead of:
void myfunc()
{
void* h = get_handle_that_must_be_released();
try { random_func(h); }
catch (...) { release_object(h); throw; }
release_object(h);
}
Do something like:
#include<boost/shared_ptr.hpp>
void my_func()
{
boost::shared_ptr<void> h(get_handle_that_must_be_released(), release_object);
random_func(h.get());
}
Create your own class with a destructor if you don't use boost.
You can use catch(...) to catch EVERYTHING, but then you don't get a an object to inspect, rethrow, log, or do anything with exactly. So... you can "double up" the try block and rethrow into one outer catch that handles a single type. This works ideally if you define constructors for a custom exception type that can build itself from all the kinds you want to group together. You can then throw a default constructed one from the catch(...), which might have a message or code in it like "UNKNOWN", or however you want to track such things.
Example:
try
{
try
{
// do something that can produce various exception types
}
catch( const CustomExceptionA &e ){ throw e; } \
catch( const CustomExceptionB &e ){ throw CustomExceptionA( e ); } \
catch( const std::exception &e ) { throw CustomExceptionA( e ); } \
catch( ... ) { throw CustomExceptionA(); } \
}
catch( const CustomExceptionA &e )
{
// Handle any exception as CustomExceptionA
}
If I recall correctly (it's been a while since I've looked at C++), I think the following should do the trick
try
{
// some code
}
catch(...)
{
// catch anything
}
and a quick google(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html) seems to prove me correct.