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

StackOverflow https://stackoverflow.com/questions/8611485

  •  27-03-2021
  •  | 
  •  

Pergunta

Will finally block execute? if I pass exit; ?

procedure someProc;
begin
    Try
      Exit;
    finally
     do_something;
    end;
end;
Foi útil?

Solução

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

Outras dicas

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.

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.

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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top