This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [basic-improvements] try/finally support for c/c++
On Wed, Nov 06, 2002 at 08:44:01AM +0000, Joseph S. Myers wrote:
> On Tue, 5 Nov 2002, Aldy Hernandez wrote:
>
> > + The @code{__try/__finally} statement consists of a @code{__try} block
>
> "/" should not be in @code here and below.
Fixed.
>
> > + containing one or statements, and a @code{__finally} block contatining
> > + one or more statements. The @code{__finally} block will execute after
> > + the @code{__try} block but before the code following the
> > + @code{__try/__finally} construct, even if the @code{__try} block exits
> > + the current function.
>
> There should be a corresponding mention of longjmp to that in the formal
> edits.
I don't understand what you want here. Could you elaborate please?
> > + Exiting out of a finally block through a @code{return} or @code{goto}
> > + has undefined behaviour.
> ^^^^ ior
fixed.
> > + The @code{__try} block is executed. After the __try block exits,
> > + control is transferred to the @code{__finally} block regardless of how
> > + the __try block exits (with the exception of program termination or
> > + longjump exits out of the try block).
>
> That's @code{longjmp}. Also use consistent terminology; you're using
> "@code{__try} block", "__try block" and "try block".
Fixed. Using "try block" and "finally block" all throughout now.
> > + The __finally block is guaranteed to execute after the __try block,
> > + provided the program does not terminate while inside such block.
> > + After the __finally block executes, the flow of the program will
> > + continue where the __try block was meant to transfer control to, had
> > + there been no __finally block.
>
> I believe the intention is that variables defined outside the try block
> are live, but variables definied within it are not, while the finally
> block is executing, regardless of how entered? Also, if the try block
> terminates by falling off the end, the intended point of transfer of
> control is after the end of the finally block?
Added Jakub's description.
> > + A @code{goto}, @code{break}, @code{return}, or @code{continue}
> > + statement can be used to transfer control out of a try block but not
> > + into one. Also, a longjump may not be used to transfer control into a
> > + try or finally block. If done, the behavior is undefined.
>
> @code{longjmp}. May it be used to jump out of such a block? All the
> rules that jumps into try blocks are not permitted (and you'll need to add
> switch to the statements that might jump into a block) should be listed as
> constraints (with corresponding testcases for the errors from the
> constraint violations); although violating them at runtime with GNU C
> computed gotos would be undefined. May a finally block be jumped into
> (and if so, where does execution pass after the finally block is
> finished)? May a finally block be jumped out of?
Richard could you elaborate here? It was my understanding that
longjmp may not be used to jump into a try/finally block or out of
one? What are the actual restrictions?
> > + statement can be used to transfer control out of a try block but not
> > + into one. If such a statement is used to transfer control into
> > +
>
> Stray partial paragraph.
Fixed.
Joseph, how does this one look?
Aldy
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.95.4.5
diff -c -p -r1.95.4.5 extend.texi
*** doc/extend.texi 21 Oct 2002 17:52:59 -0000 1.95.4.5
--- doc/extend.texi 6 Nov 2002 18:26:48 -0000
*************** extensions, accepted by GCC in C89 mode
*** 473,478 ****
--- 473,479 ----
* Target Builtins:: Built-in functions specific to particular targets.
* Pragmas:: Pragmas accepted by GCC.
* Unnamed Fields:: Unnamed struct/union fields within structs/unions.
+ * Try-finally:: Try/finally construct.
* Thread-Local:: Per-thread variables.
@end menu
*************** struct @{
*** 6506,6511 ****
--- 6507,6747 ----
It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
Such constructs are not supported and must be avoided. In the future,
such constructs may be detected and treated as compilation errors.
+
+ @node Try-finally
+ @section Try/finally exceptions
+ @cindex Try/finally exceptions
+ @cindex try-finally
+ @cindex __try
+ @cindex __finally
+
+ The @code{__try}/@code{__finally} statement consists of a try block
+ containing one or more statements, and a finally block contatining one
+ or more statements. The finally block will execute after the try
+ block but before the code following the @code{__try}/@code{__finally}
+ construct, even if the try block exits the current function.
+
+ For example:
+
+ @example
+ __try @{
+ do_something();
+ return;
+ @} __finally @{
+ fin = 1;
+ @}
+ @end example
+
+ In the above example, @code{fin} will get set to 1 before the function
+ returns to its caller.
+
+ You can nest more than one @code{__try}/@code{__finally} construct.
+
+ Since C++ already has a @code{try} keyword, both @code{try} and
+ @code{__try} variations are allowed. Also, the C++ implementation
+ allows using @code{__finally} after a series of
+ @code{try}/@code{catch} blocks. The finally block will be executed
+ after the applicable @code{catch}. For example:
+
+ @example
+ try @{
+ do_something();
+ @} catch (blah) @{
+ x = 0;
+ @} catch (...) @{
+ x = 1;
+ @} __finally @{
+ y = 2;
+ @}
+ @end example
+
+ In the example above, @code{y} will be set after the set to @code{x}
+ in the catch clause.
+
+ It is possible to have a C @code{__try}/@code{__finally} construct
+ call C++ code that throws an exception. As part of the unwind
+ process, the C finally block will be called before control is returned
+ to the C's calling routine.
+
+ Exiting out of a finally block through a @code{return} or @code{goto}
+ has undefined behavior.
+
+ GCC's @code{__try}/@code{__finally} implementation is analogous to the
+ corresponding construct in Java.
+
+ @menu
+ * C99 Try-Finally Edits::
+ * C++98 Try-Finally Edits::
+ @end menu
+
+ @node C99 Try-Finally Edits
+ @subsection ISO/IEC 9899:1999 Edits for Try-Finally
+
+ The following are a set of changes to ISO/IEC 9899:1999 (aka C99)
+ that document the exact semantics of the language extension.
+
+ @itemize @bullet
+ @item
+ @cite{6.4.1 Keywords}
+
+ Add @code{__try}.
+ Add @code{__finally}.
+
+ @item
+ @cite{6.8.2b The try/finally statement}
+
+ New section.
+
+ @quotation
+ Syntax:
+ @example
+ try-finally-statement:
+ @b{__try}
+ @i{compound-statement}
+ @b{__finally}
+ @i{compound-statement}
+
+ @end example
+ @end quotation
+
+ The try block is executed. After the __try block exits, control is
+ transferred to the finally block regardless of how the try block exits
+ (with the exception of program termination or @code{longjmp} exits out
+ of the try block).
+
+ If a try block was exited by @code{return}, then the function returns
+ after finishing the finally block (unless inside other try block). If
+ a try block is exited normally, then execution continues after the end
+ of the finally block. If a try block is exited through an exception
+ being thrown (or forced unwinding), then after finally block exits,
+ the exception is resumed or forced unwinding continues.
+
+ A @code{goto}, @code{break}, @code{return}, or @code{continue}
+ statement can be used to transfer control out of a try block but not
+ into one. Also, a @code{longjmp} may not be used to transfer control
+ into a try or finally block. If done, the behavior is undefined.
+
+ This construct is meant to provide a mechanism through which a series
+ of cleanups can be executed upon exit from a block (the try block).
+ If somewhere inside the try block an exception occurs and the
+ corresponding exception handler lies in the frame above the finally
+ block, the finally block will execute before control reaches the
+ exception handler above.
+
+ This mechanism is by no ways a complete exception handling system for
+ C.
+
+ @end itemize
+
+ @node C++98 Try-Finally Edits
+ @subsection ISO/IEC 14882:1998 Edits for Try-Finally
+
+ @itemize @bullet
+ @item
+ @cite{2.11 Keywords: Table 3}
+
+ Add @code{__finally}.
+
+ @item
+ @cite{15 Exception handling}
+
+ Rename the @code{handler-seq} production by the following:
+
+ @example
+ handler-seq:
+ handler-seq-catch finally-block-opt
+ finally-block
+
+ handler-seq-catch:
+ handler handler-seq-catch
+
+ finally-block-opt:
+ finally-block
+
+ finally-block:
+ @b{__finally} compound-statement
+ @end example
+
+ Add new text at the end of section 2.
+
+ @quotation
+ When control is transferred from a try block to a destination (say
+ destination @b{A}), be it through a @code{continue}, @code{break},
+ @code{return}, or @code{goto}, control is first redirected to the
+ finally block. When the finally block finishes, control is then
+ transferred to destination @b{A}.
+ @end quotation
+
+ Add to code below to the example in section 3.
+
+ @example
+ __finally
+ @{
+ // code to be executed after the try block and
+ // applicable catch block is executed.
+ @}
+ @end example
+
+ Add new example at the end of section 3.
+
+ @quotation
+ The following code samples are equivalent.
+ @end quotation
+
+ @example
+ A)
+ __try @{
+ A;
+ @} catch (...) @{
+ B;
+ @} __finally @{
+ C;
+ @}
+
+ B)
+ __try @{
+ __try @{
+ A;
+ @} catch (...) @{
+ B;
+ @}
+ @} __finally @{
+ C;
+ @}
+ @end example
+
+ @item
+ @cite{15.2 Constructors and destructors}
+
+ Add new text to section 3.
+
+ @quotation
+ If code within a try block (or within code called from a try
+ block) causes an exception that is not caught by the subsequent
+ catch blocks, the code in __finally executes on the path up to
+ the handler that will catch the exception (if one is available).
+
+ Even though the code in the finally block is run on exit from the try
+ block, exiting a try block with a corresponding finally block via
+ longjmp or computed goto has undefined behavior.
+ @end quotation
+
+ Add new text to section 7.
+
+ @quotation
+ If the try block has a corresponding finally block, the code in the
+ finally block will execute before control reaches the dynamically
+ surrounding try block.
+ @end quotation
+
+ Add new section 2.
+
+ @quotation
+ If the finally block contains a jump outside stated block, the
+ program is ill-formed and the behavior is undefined.
+ @end quotation
+
+ @end itemize
@node Thread-Local
@section Thread-Local Storage