Do function try blocks on non-contructor functions have any disadvantage?

93 views Asked by At

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?

2

There are 2 answers

1
Jarod42 On BEST ANSWER
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.

1
for_stack On

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