[Lazarus] try finally exit

Hans-Peter Diettrich DrDiettrich1 at aol.com
Sat Jun 29 14:12:04 CEST 2013


Jürgen Hestermann schrieb:
> Am 2013-06-28 22:34, schrieb Bart:
>  > On 6/28/13, Junior <lazarus.linux at gmail.com> wrote:
>  >> strList.TStringList.Create;
>  >> try
>  >>    if Pos('blablabla',strList.Text) = 0 then
>  >>      Exit;
>  >> finally
>  >>     strList.Free;
>  >> end;
>  >> Adding "Exit", the finally is executed?
>  > Just wondering. Why couldn't you test that yourself?
> 
> Is that the way programming is done today: "There is no documentation, 
> just figure it out yourself"?
> I can't believe it.

Such documentation exists in most cases, but it may be hard to find, in 
detail in a Wiki :-(

> How can the programmer be sure that test results apply under all 
> circumstances?

Depends on the test code and results ;-)

> Does he have to write test routines for all possible szenarious?

At least for all scenarios where the user doesn't trust the 
documentation or answers to his questions. Sometimes very special code 
can reveal compiler bugs, when the program does not behave as it should.

> What about nested try..finaly commands?

Think of every try-finally block as a room, with one entry and one exit 
door. Whenever the try block is left, execution must pass through its 
exit door (finally block). Only after exiting from all rooms, floors 
etc. this way, the subroutine is finally left (at its "end;").

Not so obvious: code *after* the finally-end is *not* executed after an 
"exit;"!

procedure TestExit;
begin
   try
     WriteLn('enter try-finally block');
     exit;
   finally
     WriteLn('reached finally');
   end;
   WriteLn('compiler error: this should never be reached!');
end;

> Is it guaranteed that all finally parts are executed?

Yes, even in less obvious cases. When an exception occurs, *all* pending 
finally blocks execute, in *all* subroutines on the call stack. 
"Pending" here means those try-finally blocks, which had been entered 
before the subroutine call, but have not alreday been left. This *stack 
unwinding* proceeds until the top level subroutine, or until the 
exception is caught by an try-except block. The exception handler (in 
this except block) resets the exception, so that from this point on 
execution proceeds as usual.

The major difference between try-finally and try-except is that 
"finally" code executes *always*, regardless of how the try-finally 
block is left. The "except" code instead is executed *only* after an 
exception occured, not during normal execution. When an exception 
handler does *not* handle the current exception type, or re-raises the 
exception, or raises another exception, stack unwinding continues until 
the next enclosing try-except block.

DoDi





More information about the Lazarus mailing list