Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to goto out of try block?

Tags:

c++

standards

I have some code that I've inherited from someone very clever where they like to use gotos to leave the try block, jumping completely around the catch blocks.

It definitely works, and I suspect this is legal (I think that the C++ standard says that on exit from a scope, everything gets cleaned up properly, and I assume that applies to whatever the compiler had to do to implement exceptions on my platform).

Is this really legit? It's NOT something I'd ever write (it's too clever by half), but it's clearly working, and I just want to understand why this is OK.

like image 426
Michael Kohne Avatar asked Jul 12 '12 19:07

Michael Kohne


4 Answers

It can be legit and it depends on what the code does. For example I have written code that jumps out of a catch block, and it's used in a language's runtime library (for simplicity, the code that uses the runtime library does not implement the itanium exception handling, but is implemented using longjmp/setjmp). The runtime library however, through the C++ exceptions, does use it; and a mechanism is needed to cleanly transfer control between them.

try {
  doSomethingThatMayFail();
} catch(DiagnosticException&) {
  goto unwind;
}

if(0) {
unwind:
  longjmp(&lastSafePoint, 0);
}

I put this into a macro so that it's very convenient to write. The goto here is necessary to cleanup resources allocated during exception handling of the diagnostic exception.

As always, don't say "NEVER use this feature". Every use must be carefully thought about, instead.

like image 194
Johannes Schaub - litb Avatar answered Oct 19 '22 18:10

Johannes Schaub - litb


Standard Says yes, it's legal & well-defined:

C++2003: 6.6 Jump Statements

On exit from a scope (however accomplished), destructors (12.4) are called for all constructed objects with automatic storage duration (3.7.2) (named objects or temporaries) that are declared in that scope, in the reverse order of their declaration. Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of variables with automatic storage duration that are in scope at the point transferred from but not at the point transferred to. (See 6.7 for transfers into blocks). [Note: However, the program can be terminated (by calling exit() or abort()(18.3), for example) without destroying class objects with automatic storage duration. ]

I choose not to comment on the religious implications of using goto in the first place.

like image 43
John Dibling Avatar answered Oct 19 '22 17:10

John Dibling


Even more specifically than the C++03 standard's section on jump statements, it says this about try-blocks in the "Exception handling" clause (15/2):

A goto, break, return, or continue statement can be used to transfer control out of a try block or handler. When this happens, each variable declared in the try block will be destroyed in the context that directly contains its declaration.

C++11 contains the same wording.

Note however, that's it's not OK to jump into a try-block using a goto (or switch):

A goto or switch statement shall not be used to transfer control into a try block or into a handler.

like image 20
Michael Burr Avatar answered Oct 19 '22 16:10

Michael Burr


It's legal. It's bad code. Don't do it. Don't use goto.

like image 31
Jonathan Grynspan Avatar answered Oct 19 '22 16:10

Jonathan Grynspan