11

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.

rekire
  • 47,260
  • 30
  • 167
  • 264
deworde
  • 2,679
  • 5
  • 32
  • 60
  • It gets terminated, but what do you want me to do?, provide you a compiler to execute this program so that you can verify the result. – Narendra N Feb 18 '10 at 14:02
  • All a compiler will do is compile it. And it will compile, because there's nothing about the *definition* of handle to warn a user that it'll definitely require a loaded exception. Compilers can't tell you much useful about undefined behaviour, especially something like this that won't be picked up until run-time. – deworde Feb 18 '10 at 19:40

3 Answers3

18

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.

John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • Well, there's no sane reason to call "handle()" if you're not inside a catch block, but I was interested in whether what happened would be defined. That was a perfect answer. Thanks! – deworde Feb 18 '10 at 19:57
7

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.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
1

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.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • 1
    http://stackoverflow.com/questions/2183113/using-catch-ellipsis-for-post-mortem-analysis – SF. Feb 18 '10 at 14:07
  • 3
    This is completely irrelevant to my question. Also, it's inaccurate, as SF's shown above. There are plenty of perfectly good reasons to use (...), as long as you handle it correctly. For example, suppose I want to release a lock on something that's shared. I could wait till it reaches a destructor, but better to do it as soon as I'm sure I no longer need it. I could then rethrow from inside the catch(...){} block if I wanted to ensure that the access violations and bugs still led to termination. – deworde Feb 18 '10 at 19:44