1

Possible Duplicate:
Difference between try-catch syntax for function

What is the difference in the utility and behavior of these try-catch blocks? When would I prefer one form over the other?

int f() {
  try {
    ...
  } catch(...) {
    ...
  }
}

int f() try {
  ...
} catch (...) {
  ...
}
Community
  • 1
  • 1
Robᵩ
  • 163,533
  • 20
  • 239
  • 308

2 Answers2

6

If the entire body must go into the exception block, I tend to prefer the 2nd form as it's easier to read (e.g. one less indentation level).

However, the main place where this makes a difference is in constructors. Consider:

Foo::Foo ()
try : member_with_throwing_constructor(initial_value)
{
}
catch ( ... )
{
     // will process exceptions thrown by `member_with_throwing_constructor`

     // this will be added by the compiler if you
     // don't finish by a `throw ...` statement.
     throw;
}

and

Foo::Foo ()
    : member_with_throwing_constructor(initial_value)
{
    try
    {
    }
    catch ( ... )
    {
        // does not catch exceptions thrown in constructor
        // of `member_with_throwing_constructor`.
    }
    // can keep processing if `catch` handler does not `return` or `throw`.
}

These two code snippets have radically different behavior. The first one will catch exceptions raised in data member constructors (usually through the initializer list, but default constructors apply too) and will automatically re-raise the exception because the instance could not be created safely. The second form does not cover data member initialization and allows you to choose whether to keep the object or not.

I also like to add a global try-catch in main() to help with debugging uncaught exceptions. The following snippet:

int main ( int, char ** )
try
{
    // main program...
}
catch ( const std::exception& error )
{
    std::cerr << "Uncaught exception: '" << error << "'." << std::endl;
    return (EXIT_FAILURE);
}
catch ( ... )
{
    std::cerr << "Uncaught exception of unknown type." << std::endl;
    return (EXIT_FAILURE);
}

Some people will argue that not catching the exceptions allows the program to crash and you can get a core dump to help with debugging. While this may be useful in debug mode, as it can help the debugger point you to the exact line of code that raised the exception, I like to ship programs that don't crash, and I can show the user a message saying a bug report was submitted.

André Caron
  • 44,541
  • 12
  • 67
  • 125
2

Function try-catch blocks are only useful in constructors, and even then, not very useful at all. It's best to just forget they exist.

Puppy
  • 144,682
  • 38
  • 256
  • 465