2

Function try blocks are a special form of function bodies, for example:

int f() try {
  // function body
} 
catch {
  // one or more catch-clauses.
}

The primary purpose is for usage in constructors, in order to log exceptions thrown by the constructor of any base class. However, it is allowed to use them in regular functions, too.

There exist some (quite old) questions on this, asking why would we need it for regular functions, e.g. Function try blocks, but not in constructors. However, my question is more in slightly in another direction: Can I use it in regular functions as replacement for a regular try-block without concerns? Let's say, just for aesthetical reasons?

I develop a C-Interface for a C++-Library and need to encapsulate each interface-function with a try-block to catch any exceptions. Thus, I would like to avoid an additional curly-bracket-block in each function...

Just one thing, which raised my concerns: In the answer https://stackoverflow.com/a/11535436/6695750, davka cites an article from 2000, claiming that you can't return a value from a catch-block corresponding to a function-try-block. I tested with gcc 5.4.0, there I can return a value from the catch-block without problems. Is this standard, or a non-standard extension of gcc?

Community
  • 1
  • 1
ralfg
  • 552
  • 2
  • 11
  • I don't see any pitfall, except for constructor/destructor which rethrows. – Jarod42 Aug 24 '16 at 07:53
  • The [second answer you're quoting](http://stackoverflow.com/a/11535436/1023390) is simply wrong (and was so already at the time of creation). – Walter Aug 24 '16 at 08:17
  • One (small) pitfall is that it is unexpected. If you keep the code simple (C layer just calls the C++ layer and handles exceptions) that's fine. If your code tends to become more complex/complicated over time ( as some of mine does :) ) this could turn into cruft over the years - then you may be better off using an exception handling function and passing your C++ code through it as visitors / lambdas. – utnapistim Aug 24 '16 at 08:52

2 Answers2

3
int f() try {
  // function body
} 
catch (/*..*/){
  // one or more catch-clauses.
}

is equivalent to

int f() {
    try {
      // function body
    } 
    catch (/*..*/){
      // one or more catch-clauses.
    }
}

for regular functions.

Only constructor/destructor has special treatment as the catch blocks throw a exception(implicitly or explicitly).

see also the docu here.

Walter
  • 44,150
  • 20
  • 113
  • 196
Jarod42
  • 203,559
  • 14
  • 181
  • 302
2

Can I use it in regular functions as replacement for a regular try-block without concerns?

In some case you CANNOT use function-try-block: You CANNOT access any local variables in the the catch clause.

void g() {
    int i = 2;
    try {
        throw 2.3;
    } catch (double d) {
        cout << i << endl;   // OK. you can access i
        cout << d << endl;
    }
}

void f() try {
    int i = 2;
    throw 2.3;
} catch (double d) {
    cout << i << endl;   // FAIL! i is out of scope, you CANNOT access it.
    cout << d << endl;
}
for_stack
  • 21,012
  • 4
  • 35
  • 48
  • Yes, for sure. In g(), the try-block does not embrace the whole function body, and thus it is obvious, that it is not equivalent to a function-try-block. – ralfg Aug 24 '16 at 08:48