5
votes

Are there any practical difference between the two coding patterns in Delphi:

Version 1

try
  try
    {Do something}
  finally
    {Do tidy up}
  end
except
  {Handle exception}
end;

Version 2

try
  try
    {Do something}
  except
    {Handle exception}
  end
finally
  {Do tidy up}
end;
2
As an aside, I found a rather wacky x64 bug related to finally blocks that mean they can get called twice! qc.embarcadero.com/wc/qcmain.aspx?d=108457 - David Heffernan
The code does not show where a protected resource is allocated (SomeObject.Create). Is it in the do something part or earlier? - mjn
It's unfortunate that finally blocks and except blocks are both introduced with the same try keyword because they're otherwise orthogonal concepts. - Rob Kennedy

2 Answers

6
votes

There are two differences:

  1. The relative order in which the except and finally blocks execute differs. In version 1, the finally executes before the except. In version 2 the excecution order is reversed.
  2. In version 1, if the finally block raises, then it will be handled by the except block. In version 2, if the finally block raises, then it will be handled by the next containing exception handler, i.e. outside this code.

Usually you aren't concerned about finally blocks that raise. You simply don't expect that to happen and if it does, something is probably very broken.

So the difference that counts is whether the finally runs before the exception handler, or vice versa. Sometimes it doesn't matter, but it often does make a difference.

2
votes

When you use try..except below lines executed.

Resource := TAbstractResource.Create;
try
  Resource.DoSomeThing;
except
  On E:Exception Do 
   HandleException(E);
end;
FreeAndNil(Resource);