5

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; } 
1
  • by the way your code looks more C_ish_ than C++_ish_ , just get used to code in C++ if you pick C++ as language of choice, this way your code can easily become a weird mix of languages without any benefit at all and can only make your life harder learning nothing new and useful. It's true that the C is supported under C++ without problems, but just try to have a simpler and much more linear approach when coding. Commented Oct 16, 2012 at 0:16

5 Answers 5

5

Your throw; statement tries to rethrow a current exception but there probably isn't one. You need something like

throw some_exception_object(); 
Sign up to request clarification or add additional context in comments.

3 Comments

I'd recommend throw std::runtime_error("message"), but I have seen throw 42 (which I believe can only be caught with catch (...)).
@MaxLybbert: It could be caught with catch (int n), but yeah, throwing non-class types is not recommended for "real" programs.
Well, as far as recommendation for exceptions go, I'd recommend to only ever throw types derived from std::exception but probably actually being derived from one of the standard exceptions. That wasn't the question, though ;-)
4

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.

4 Comments

It's a bit ambiguous to say '[you must use throw by itself inside of a catch block], because it suggests a syntactical limitation. In truth it's okay to rethrow whenever an exception is active -- regardless of scope.
@LucDanton: I did not say you must use throw by itself, I said the only place you can use throw by itself is inside a catch. There is no active exception if you are not inside a catch.
The throw is not in a catch block directly, but it is being called in the context of a catch block. That is fine.
4

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!

Comments

1

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

Comments

1

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; } } 

1 Comment

Hint: catching exceptions by non-constant reference for no good reason is a bad practice. Unless you really need to modify the object, catch by constant reference. This allows compiler to perform more optimizations.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.