This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]