DELPHI - except 块中的额外分号,有什么用吗? except 或 end 之前的可选分号,有或没有哪个更好?
DELPHI - Extra semi-colons in except blocks, any purpose? Optional semi-colon before except or end, What's better with or without?
我正在使用 Delphi 10.3.3 中存在一些分号异常的应用程序。我一直在阅读一些分号是可选的,具体取决于编译器,而不是在语句之间。多年来,我一直认为这是 Delphi 编译器允许的错误。如果应用程序在任何块结束语句之前被删除,我可以看到应用程序编译。
[except] 和 [end] 之间的分号是否用于代码中的任何目的,例如更快的 运行 时间或抛出一些默认异常,或其他目的?这会引发任何随机编译或 运行 时间错误吗?
在结尾或 except 之前的最后一行留下分号会加快 运行时间吗?一种方式比另一种方式更容易出错,或者更容易出现随机编译或 运行 时间错误?
这里是可以拖放到任何测试项目中的代码,其中的表单具有编辑框、按钮和使用拖放默认设置创建的备注框。
function TForm1.isThisUseful(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
;
end;
result := (i > 0)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if isThisUseful(Edit1.Text)
then
Memo1.Text := 'Yes, it is useful'
else
Memo1.Text := 'This is a waste of time.'
end;
tl;dr:没有任何区别。
try
// do stuff
except
;
end;
这个分号可以去掉。它绝对没有任何作用。它没有好处,也没有坏处(除了可能会使源代码看起来很奇怪,您应该避免这种情况1)。
begin
DoThis;
DoThat;
end;
由于在 Delphi 中,分号 分隔 语句,所以 end
之前的最后一个分号不是必需的。它绝对没有任何作用。喜欢不喜欢主要是个人喜好问题(我个人是有时吃有时不吃)。
使用这个分号的一个好处可能是您可以将此行不加修改地移动或复制到另一个地方,在那里它不是它的最后一条语句堵塞。同样,您也可以在这行代码之后直接插入一条新语句,而无需添加分号。恕我直言,这些都是非常的小好处;如果有必要,添加分号并不难。
奖金评论: 但是,result := (i > 0)
对我来说确实很奇怪。我期望 Result := i > 0
,没有不必要的括号。 (这可能是因为 20 多年来我几乎每天都在 Delphi 编程。)
奖励评论 2: 注意编译器很乐意接受
begin
DoThis;;
DoThat;
end;
还有。它只是忽略多余的分号。但是上面的代码片段在我看来 非常 难看,而且我总是觉得开发人员不先阅读代码就选择提交代码很奇怪。
奖励评论 3: Ken Bourassa 写了一个 给出了分号存在或不存在的场景示例 [= =54=]影响程序。但还有一个更可怕的例子:
case i of
0:
DoA;
1:
DoB;
2:
if j = 0 then
DoC{;}
else
DoD;
end;
1 在这种情况下,您还可以争辩说分号有一个用途:它 "highlights" 空的 except
块,使其稍微容易一些快速发现。因此,这可能是故意的。但有人可能会争辩说,突出显示它的更好方法是包含像 // Do nothing
或 // Just carry on
这样的注释。 (而且,在很多情况下,如果不是大多数情况,空 except
块根本不好。)
除了安德烈亚斯的回答...
有 1 种情况你肯定(或者,至少,最有可能)不想留下分号,它在 "then" 之后。下面的代码会在消息框中显示"B"
procedure TForm3.FormCreate(Sender: TObject);
var
S : String;
begin
S := 'A';
if 1 = 2 then;
S := 'B';
ShowMessage(S);
end;
据我所知,这是插入分号会自行更改代码生成的唯一情况。
我想我会尝试一些测量,在这个 D7 测试程序上使用 NexusDB's Quality Suite 的线路定时器:
{$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.
其中包含问题中 isThisUseful
函数的两个版本,一个在 except
块中有分号,一个没有分号。 运行 这段代码的结果(对布局略有损坏表示歉意)如下:
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 -
请注意,第 21 行(try ...except
块中的分号)没有记录时间,原因很简单,正如预期的那样,没有为其生成代码。
为了完整性,以下是isThisUseful1
和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
(我一直在斗鸡眼试图自己比较这些,并且不会浪费我的时间 运行 他们过去了 BeyondCompare)。
无论如何,我认为这表明正如我自己和其他人所说,编译器不会为 try...except
块中仅包含分号的行生成代码,并且它不应该在其他任何地方生成代码,要么,尽管如前所述,在某些情况下,分号的存在或其他方式会改变代码的语义,从而改变生成的代码。
感谢所有对此 post 的反馈。我想总结几点..
分号改变了应用程序的编译方式。因此,应用程序的大小可能会发生微小的变化。因此,它似乎是应用程序中的硬或分支开关终结器。也就是说,它可能应该在每个结束时
尝试除了结束;在每个 except 或 finally 之前,以及在每个循环的结尾,无论后面是什么,以确保编译是干净的并且始终如一。
但不应该是另一个 [end] 语句之前的 if-[end] 中遗漏的问题,或者作为不存在其他代码的地方的附加项目。但可能在循环内多一个分号,并不是最好的主意。
我正在使用 Delphi 10.3.3 中存在一些分号异常的应用程序。我一直在阅读一些分号是可选的,具体取决于编译器,而不是在语句之间。多年来,我一直认为这是 Delphi 编译器允许的错误。如果应用程序在任何块结束语句之前被删除,我可以看到应用程序编译。
[except] 和 [end] 之间的分号是否用于代码中的任何目的,例如更快的 运行 时间或抛出一些默认异常,或其他目的?这会引发任何随机编译或 运行 时间错误吗?
在结尾或 except 之前的最后一行留下分号会加快 运行时间吗?一种方式比另一种方式更容易出错,或者更容易出现随机编译或 运行 时间错误?
这里是可以拖放到任何测试项目中的代码,其中的表单具有编辑框、按钮和使用拖放默认设置创建的备注框。
function TForm1.isThisUseful(this : string): boolean;
var
i: Integer;
begin
result := false;
try
if this = ''
then
i := 0
else
i := 1
except
;
end;
result := (i > 0)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if isThisUseful(Edit1.Text)
then
Memo1.Text := 'Yes, it is useful'
else
Memo1.Text := 'This is a waste of time.'
end;
tl;dr:没有任何区别。
try
// do stuff
except
;
end;
这个分号可以去掉。它绝对没有任何作用。它没有好处,也没有坏处(除了可能会使源代码看起来很奇怪,您应该避免这种情况1)。
begin
DoThis;
DoThat;
end;
由于在 Delphi 中,分号 分隔 语句,所以 end
之前的最后一个分号不是必需的。它绝对没有任何作用。喜欢不喜欢主要是个人喜好问题(我个人是有时吃有时不吃)。
使用这个分号的一个好处可能是您可以将此行不加修改地移动或复制到另一个地方,在那里它不是它的最后一条语句堵塞。同样,您也可以在这行代码之后直接插入一条新语句,而无需添加分号。恕我直言,这些都是非常的小好处;如果有必要,添加分号并不难。
奖金评论: 但是,result := (i > 0)
对我来说确实很奇怪。我期望 Result := i > 0
,没有不必要的括号。 (这可能是因为 20 多年来我几乎每天都在 Delphi 编程。)
奖励评论 2: 注意编译器很乐意接受
begin
DoThis;;
DoThat;
end;
还有。它只是忽略多余的分号。但是上面的代码片段在我看来 非常 难看,而且我总是觉得开发人员不先阅读代码就选择提交代码很奇怪。
奖励评论 3: Ken Bourassa 写了一个
case i of
0:
DoA;
1:
DoB;
2:
if j = 0 then
DoC{;}
else
DoD;
end;
1 在这种情况下,您还可以争辩说分号有一个用途:它 "highlights" 空的 except
块,使其稍微容易一些快速发现。因此,这可能是故意的。但有人可能会争辩说,突出显示它的更好方法是包含像 // Do nothing
或 // Just carry on
这样的注释。 (而且,在很多情况下,如果不是大多数情况,空 except
块根本不好。)
除了安德烈亚斯的回答...
有 1 种情况你肯定(或者,至少,最有可能)不想留下分号,它在 "then" 之后。下面的代码会在消息框中显示"B"
procedure TForm3.FormCreate(Sender: TObject);
var
S : String;
begin
S := 'A';
if 1 = 2 then;
S := 'B';
ShowMessage(S);
end;
据我所知,这是插入分号会自行更改代码生成的唯一情况。
我想我会尝试一些测量,在这个 D7 测试程序上使用 NexusDB's Quality Suite 的线路定时器:
{$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.
其中包含问题中 isThisUseful
函数的两个版本,一个在 except
块中有分号,一个没有分号。 运行 这段代码的结果(对布局略有损坏表示歉意)如下:
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 -
请注意,第 21 行(try ...except
块中的分号)没有记录时间,原因很简单,正如预期的那样,没有为其生成代码。
为了完整性,以下是isThisUseful1
和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
(我一直在斗鸡眼试图自己比较这些,并且不会浪费我的时间 运行 他们过去了 BeyondCompare)。
无论如何,我认为这表明正如我自己和其他人所说,编译器不会为 try...except
块中仅包含分号的行生成代码,并且它不应该在其他任何地方生成代码,要么,尽管如前所述,在某些情况下,分号的存在或其他方式会改变代码的语义,从而改变生成的代码。
感谢所有对此 post 的反馈。我想总结几点..
分号改变了应用程序的编译方式。因此,应用程序的大小可能会发生微小的变化。因此,它似乎是应用程序中的硬或分支开关终结器。也就是说,它可能应该在每个结束时 尝试除了结束;在每个 except 或 finally 之前,以及在每个循环的结尾,无论后面是什么,以确保编译是干净的并且始终如一。
但不应该是另一个 [end] 语句之前的 if-[end] 中遗漏的问题,或者作为不存在其他代码的地方的附加项目。但可能在循环内多一个分号,并不是最好的主意。