Sign in Join
Wiki copytemporary

Finally: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Finally

OldNewLine
1+Back to [[Reserved words]].
2+
3+The reserved word `finally` identifies a [[Block|block]] of code that should always be processed, regardless of whether the preceding `try` block was fully executed or has been exited early (in case of an [[Exception]], [[Exit]], [[Break]] or [[Continue]]).
4+
5+## Examples
6+
7+Simple example:
8+
9+``` pascal
10+begin
11+ ...
12+ try
13+ ... // code to check
14+ finally
15+ ... // code which should always be executed even if try exits early
16+ end;
17+ ...
18+end;
19+```
20+
21+Example with error handling:
22+
23+``` pascal
24+begin
25+ ...
26+ try
27+ try
28+ ... // code to check
29+ except
30+ ... // error handling
31+ end;
32+ finally
33+ ... // code which should always be executed even if try exits early
34+ end;
35+ ...
36+end;
37+```
38+
39+## Non-Exception Code
40+
41+Despite the name, Try-Finally is not strictly tied to the usage of exceptions, and also provides benefits in code where no exceptions can be raised. The reason for this is that the Finally block will always be executed, even if the try block exits early.
42+
43+This can be very useful e.g. for the [[Break Fast Break Even]] paradigm, where [[Exit]] or other jumps (such as [[Break]] or [[Continue]]) are used:
44+
45+``` pascal
46+function CheckFormat(const CSVString: String): Boolean;
47+var
48+ sl: TStringList;
49+begin
50+ Result := False;
51+ sl := TStringList.Create;
52+ try
53+ sl.Delimiter := ';';
54+ sl.StrictDelimiter := True;
55+ sl.DelimitedText := CSVString;
56+
57+ if sl.Count <> RowCount then
58+ Exit; // Will automatically execute the finally block before exiting
59+ // Check field data, e.g.
60+ if not isNumber(sl[1]) then
61+ Exit; // Will automatically execute the finally block before exiting
62+ // ...
63+ finally
64+ sl.Free;
65+ end;
66+ // All checks passed
67+ Result := True;
68+end;
69+```
70+
71+Because of the try-finally, the code can simply call exit, and the finally block ensures that sl will be freed afterwards. Without the try-finally, each of these blocks would require a seperate sl.Free call:
72+
73+``` pascal
74+function CheckFormat(const CSVString: String): Boolean;
75+var
76+ sl: TStringList;
77+begin
78+ Result := False;
79+ sl := TStringList.Create;
80+ sl.Delimiter := ';';
81+ sl.StrictDelimiter := True;
82+ sl.DelimitedText := CSVString;
83+
84+ if sl.Count <> RowCount then
85+ begin
86+ sl.Free;
87+ Exit;
88+ end;
89+
90+ if not isNumber(sl[1]) then
91+ begin
92+ sl.Free;
93+ Exit;
94+ end;
95+
96+ // ...
97+
98+ sl.Free;
99+end;
100+```
101+
102+Therefore try-finally can even in code without exceptions, help to ensure that the cleanup is performed, without having to consider each exit point individually
103+
104+## Caveats
105+
106+The `finally` part is *not* executed if a [`halt`](https://www.freepascal.org/docs-html/rtl/system/halt.html) occurred.
107+
108+## See also
109+
110+- [[Try]]
111+- [[Except]]
112+- [[Avoiding implicit try finally section]]
113+
114+---
115+*From the Free Pascal wiki, page "Finally", as it stood on 2023-08-14 after a change by Alextpp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history