user180574
user180574

Reputation: 6084

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

Upvotes: 5

Views: 1932

Answers (5)

Frederic Lachasse
Frederic Lachasse

Reputation: 721

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

Upvotes: 1

user405725
user405725

Reputation:

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!

Upvotes: 4

bengreenier
bengreenier

Reputation: 285

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

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 596206

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.

Upvotes: 4

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153830

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

throw some_exception_object();

Upvotes: 5

Related Questions