I thought I would try some measurements, using the Line Timer of NexusDB's Quality Suite on this D7 test program:
{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O-,P+,Q-,R-,S-,T-,U-,V+,W+,X+,Y+,Z1}
program semicolontest;
{$APPTYPE CONSOLE}
uses
SysUtils;
function isThisUseful1(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
;
end;
result := (i > 0)
end;
function isThisUseful2(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
end;
result := (i > 0)
end;
var
Input : String[20];
i : Integer;
Res : Boolean;
begin
Input := 'abcdefg';
writeln('Starting');
for i := 1 to 1000000 do begin
Res := isThisUseful1(Input);
Res := isThisUseful2(Input);
end;
writeln('Done');
// readln;
end.
which contains two versions of the isThisUseful
function from the question, one with, and one without the semicolon in the except
block. The results of running this code (with apologies for the slightly mangled layout) are as follows:
Line Total Time Hit Count Source
1 - {$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O-,P+,Q-,R-,S-,T-,U-,V+,W+,X+,Y+,Z1}
2 - program semicolontest;
3 -
4 - {$APPTYPE CONSOLE}
5 -
6 - uses
7 - SysUtils;
8 -
9 - function isThisUseful1(this : string): boolean;
10 - var
11 - i: Integer;
12 2.807175 1,000,000 begin
13 0.761388 1,000,000 result := false;
14 2.133202 1,000,000 try
15 1.403061 1,000,000 if this = ''
16 - then
17 - i := 0
18 - else
19 0.826841 1,000,000 i := 1
20 - except
21 - ;
22 - end;
23 0.735419 1,000,000 result := (i > 0)
24 - end;
25 -
26 - function isThisUseful2(this : string): boolean;
27 - var
28 - i: Integer;
29 1.260030 1,000,000 begin
30 0.782293 1,000,000 result := false;
31 0.894420 1,000,000 try
32 0.820860 1,000,000 if this = ''
33 - then
34 - i := 0
35 - else
36 0.873424 1,000,000 i := 1
37 - except
38 -
39 - end;
40 0.778922 1,000,000 result := (i > 0)
41 - end;
42 -
43 - var
44 - Input : String[20];
45 - i : Integer;
46 - Res : Boolean;
47 -
48 1.167140 1 begin
49 -
50 0.000036 1 Input := 'abcdefg';
51 -
52 0.641347 1 writeln('Starting');
53 0.000026 1 for i := 1 to 1000000 do begin
54 - Res := isThisUseful1(Input);
55 - Res := isThisUseful2(Input);
56 0.669066 1,000,000 end;
57 0.402661 1 writeln('Done');
58 - // readln;
59 - end.
60 -
Notice that no time is recorded for line 21, the semicolon in the try ...except
block, for the simple reason that, as expected, no code is generated for it.
For completeness, the following are disassemblies of isThisUseful1
and isThisUseful2
isThisUseful1:
Address Bytes Text Block #
00408620h [semicolontest.dpr.12] begin
00408620h 55 push ebp 1
00408621h 8BEC mov ebp, esp 1
00408623h 83C4F4 add esp, 0FFFFFFF4h ; (-0Ch) 1
00408626h 53 push ebx 1
00408627h 56 push esi 1
00408628h 57 push edi 1
00408629h 8945FC mov [ebp-04h], eax 1
0040862Ch 8B45FC mov eax, [ebp-04h] 1
0040862Fh E87CB7FFFF call System::LStrAddRef ;(00403DB0h) 1
00408634h 33C0 xor eax, eax 1
00408636h 55 push ebp 1
00408637h 689A864000 push offset @@6 1
0040863Ch 64FF30 push fs:[eax] 1
0040863Fh 648920 mov fs:[eax], esp 1
00408642h [semicolontest.dpr.13] result := false;
00408642h C645FB00 mov byte ptr [ebp-05h], 00h 1
00408646h [semicolontest.dpr.14] try
00408646h 33C0 xor eax, eax 1
00408648h 55 push ebp 1
00408649h 6872864000 push offset @@3 1
0040864Eh 64FF30 push fs:[eax] 1
00408651h 648920 mov fs:[eax], esp 1
00408654h [semicolontest.dpr.15] if this = ''
00408654h 837DFC00 cmp dword ptr [ebp-04h], 00h 1
00408658h 7507 jnz @@1 1
0040865Ah [semicolontest.dpr.17] i := 0
0040865Ah 33C0 xor eax, eax 2
0040865Ch 8945F4 mov [ebp-0Ch], eax 2
0040865Fh EB07 jmp @@2 2
00408661h [semicolontest.dpr.19] i := 1
00408661h @@1:
00408661h C745F401000000 mov dword ptr [ebp-0Ch], 01h 3
00408668h @@2:
00408668h 33C0 xor eax, eax 4
0040866Ah 5A pop edx 4
0040866Bh 59 pop ecx 4
0040866Ch 59 pop ecx 4
0040866Dh 648910 mov fs:[eax], edx 4
00408670h EB0A jmp @@4 4
00408672h @@3:
00408672h E9DDACFFFF jmp System::HandleAnyException ;(00403354h) 5
00408677h [semicolontest.dpr.21] ;
00408677h E8B8AEFFFF call System::DoneExcept ;(00403534h) 5
0040867Ch [semicolontest.dpr.23] result := (i > 0)
0040867Ch @@4:
0040867Ch 837DF400 cmp dword ptr [ebp-0Ch], 00h 6
00408680h 0F9F45FB setnle [ebp-05h] 6
00408684h 33C0 xor eax, eax 6
00408686h 5A pop edx 6
00408687h 59 pop ecx 6
00408688h 59 pop ecx 6
00408689h 648910 mov fs:[eax], edx 6
0040868Ch 68A1864000 push offset @@7 6
00408691h @@5:
00408691h 8D45FC lea eax, [ebp-04h] 7
00408694h E8BFB3FFFF call System::LStrClr ;(00403A58h) 7
00408699h C3 ret 7
0040869Ah @@6:
0040869Ah E9E1ADFFFF jmp System::HandleFinally ;(00403480h) 8
0040869Fh EBF0 jmp @@5 8
004086A1h @@7:
004086A1h 8A45FB mov al, [ebp-05h] 9
004086A4h [semicolontest.dpr.24] end;
004086A4h 5F pop edi 9
004086A5h 5E pop esi 9
004086A6h 5B pop ebx 9
004086A7h 8BE5 mov esp, ebp 9
004086A9h 5D pop ebp 9
004086AAh C3 ret 9
isThisUseful2:
Address Bytes Text Block #
00408620h [semicolontest.dpr.12] begin
00408620h 55 push ebp 1
00408621h 8BEC mov ebp, esp 1
00408623h 83C4F4 add esp, 0FFFFFFF4h ; (-0Ch) 1
00408626h 53 push ebx 1
00408627h 56 push esi 1
00408628h 57 push edi 1
00408629h 8945FC mov [ebp-04h], eax 1
0040862Ch 8B45FC mov eax, [ebp-04h] 1
0040862Fh E87CB7FFFF call System::LStrAddRef ;(00403DB0h) 1
00408634h 33C0 xor eax, eax 1
00408636h 55 push ebp 1
00408637h 689A864000 push offset @@6 1
0040863Ch 64FF30 push fs:[eax] 1
0040863Fh 648920 mov fs:[eax], esp 1
00408642h [semicolontest.dpr.13] result := false;
00408642h C645FB00 mov byte ptr [ebp-05h], 00h 1
00408646h [semicolontest.dpr.14] try
00408646h 33C0 xor eax, eax 1
00408648h 55 push ebp 1
00408649h 6872864000 push offset @@3 1
0040864Eh 64FF30 push fs:[eax] 1
00408651h 648920 mov fs:[eax], esp 1
00408654h [semicolontest.dpr.15] if this = ''
00408654h 837DFC00 cmp dword ptr [ebp-04h], 00h 1
00408658h 7507 jnz @@1 1
0040865Ah [semicolontest.dpr.17] i := 0
0040865Ah 33C0 xor eax, eax 2
0040865Ch 8945F4 mov [ebp-0Ch], eax 2
0040865Fh EB07 jmp @@2 2
00408661h [semicolontest.dpr.19] i := 1
00408661h @@1:
00408661h C745F401000000 mov dword ptr [ebp-0Ch], 01h 3
00408668h @@2:
00408668h 33C0 xor eax, eax 4
0040866Ah 5A pop edx 4
0040866Bh 59 pop ecx 4
0040866Ch 59 pop ecx 4
0040866Dh 648910 mov fs:[eax], edx 4
00408670h EB0A jmp @@4 4
00408672h @@3:
00408672h E9DDACFFFF jmp System::HandleAnyException ;(00403354h) 5
00408677h [semicolontest.dpr.21] ;
00408677h E8B8AEFFFF call System::DoneExcept ;(00403534h) 5
0040867Ch [semicolontest.dpr.23] result := (i > 0)
0040867Ch @@4:
0040867Ch 837DF400 cmp dword ptr [ebp-0Ch], 00h 6
00408680h 0F9F45FB setnle [ebp-05h] 6
00408684h 33C0 xor eax, eax 6
00408686h 5A pop edx 6
00408687h 59 pop ecx 6
00408688h 59 pop ecx 6
00408689h 648910 mov fs:[eax], edx 6
0040868Ch 68A1864000 push offset @@7 6
00408691h @@5:
00408691h 8D45FC lea eax, [ebp-04h] 7
00408694h E8BFB3FFFF call System::LStrClr ;(00403A58h) 7
00408699h C3 ret 7
0040869Ah @@6:
0040869Ah E9E1ADFFFF jmp System::HandleFinally ;(00403480h) 8
0040869Fh EBF0 jmp @@5 8
004086A1h @@7:
004086A1h 8A45FB mov al, [ebp-05h] 9
004086A4h [semicolontest.dpr.24] end;
004086A4h 5F pop edi 9
004086A5h 5E pop esi 9
004086A6h 5B pop ebx 9
004086A7h 8BE5 mov esp, ebp 9
004086A9h 5D pop ebp 9
004086AAh C3 ret 9
(I went cross-eyed trying to compare these myself, and wasn't going to waste my time running them past BeyondCompare).
Anyway, I think this shows that as stated by myself and others, the compiler does not generate code for a line containing only a semicolon in a try...except
block, and it shouldn't do anywhere else, either, though as noted there are cases where the presence or otherwise of a semicolon changes the semantics of the code and hence the code generated.