Does the statements in the Finally block still execute in this piece of code ?
Asked Answered
B

4

29

Will finally block execute? if I pass exit; ?

procedure someProc;
begin
    Try
      Exit;
    finally
     do_something;
    end;
end;
Badlands answered 23/12, 2011 at 1:51 Comment(1)
Side note: while True do try Exit; finally Continue; end; will not compile - see Fun with Infinite Loops in Delphi and JavaAfterbrain
T
39

Yes, finally blocks always execute, even if you call Exit somewhere. They wouldn't be worth much if they weren't always executed.

Themselves answered 23/12, 2011 at 1:54 Comment(0)
P
30

The finally clause will always be executed, unless the executing thread enters a non-terminating loop, blocks indefinitely or is terminated abnormally, whilst executing the try clause.

The pertinent documentation states (emphasis mine):

The syntax of a try...finally statement is

try 
  statementList1
finally
  statementList2 
end 

where each statementList is a sequence of statements delimited by semicolons.

The try...finally statement executes the statements in statementList1 (the try clause). If statementList1 finishes without raising exceptions, statementList2 (the finally clause) is executed. If an exception is raised during execution of statementList1, control is transferred to statementList2; once statementList2 finishes executing, the exception is re-raised. If a call to the Exit, Break, or Continue procedure causes control to leave statementList1, statementList2 is automatically executed. Thus the finally clause is always executed, regardless of how the try clause terminates.

Piet answered 23/12, 2011 at 6:11 Comment(6)
+1 for listing those conditions when the finally clause is not executed.Amund
@MrLister No I did not. Read again the first paragraph.Piet
Don't forget on power outage, natural catastrophes and possible alien attacks :-)Stanleystanly
@Stanleystanly I didn't. They are covered by the catch all "terminated abnormally"! ;-)Piet
Ah, sorry. I missed that. Well, that should cover also falling piano accidents.Stanleystanly
This is the part I was looking for: once statementList2 finishes executing, the exception is re-raised.Lail
H
15

A quick test app could have answered this question really quickly.

program TestFinally;

{$APPTYPE CONSOLE}

uses
  SysUtils;

begin
  try
    WriteLn('Before exiting');
    Exit;
  finally
    WriteLine('In finally. If you see this, it was written after "Exit" was called');
    ReadLn;
  end;
end.
Hasson answered 23/12, 2011 at 4:23 Comment(0)
C
12

For the sake of completeness - finally block will not execute if the process or thread executing the try..finally block is terminated with TerminateProcess/TerminateThread.

For example, finally block will not be executed in the code below.

o := TObject.Create;
try
  TerminateThread(GetCurrentThread, 0);
finally
  o.Free;
end;
Crab answered 23/12, 2011 at 8:37 Comment(3)
Did I miss that in my answer? Maybe I should have said terminate thread abnormally rather than program.Piet
You're right, you said that. Feel free to merge my example in your answer, then I'll delete mine.Crab
I edited my text to make it a little more complete. Your answer covers that particular aspect in depth and I think merging your example into my answer would detract from the main point which is the documentation quote. Thanks and +1.Piet

© 2022 - 2024 — McMap. All rights reserved.