Delphi - try finally块是否由编译器保证正确执行?

6

我知道这个问题在其他话题上也有讨论,但我想问的正是这个问题的标题。

有没有这样的情况,即try/finally中finally不会执行?

 try
  //some error here
 finally
  //code that MUST be executed
 end;

我不是在谈论try..except/finally块的使用,我只是想知道这是否可能发生。

更新:Application.Terminate/拔掉计算机是特殊情况。


3
编译器不会给出超越世界末日或您的个人电脑的任何保证,以先到者为准。但在所有重要情况下,即当 finally 块仍然可以执行某些有用操作时,它将被执行。 - H H
1
我正在查看这个问题https://dev59.com/7XA75IYBdhLWcg3wFEyb - 看来Java开发人员并没有考虑过蚯蚓洞/世界末日等。我必须承认,Delphi开发人员有幽默感。 - RBA
4个回答

22

try..finally 保证 finally 块中的代码将会执行,无论受保护块中是否发生异常。当然,在 finally 块能够执行之前如果进程被终止,例如通过 TerminateProcess 或关闭电源,则该规则不适用。在受保护块中的无限循环也可能阻止 finally 块的执行。


16
一个相关的问题是,并不是 finally 中的所有代码都是保证会被执行的。例如,你可能在 finally 中有三个语句,但是第二个语句执行时出现了异常,那么第三个语句就不会执行了。一个很好的例子就是试图释放未分配的对象。 - Chris Thornton
保证更加强大。在 finally 块之外使用 exit、break 或 continue 将导致 finally 块运行。我猜 goto 也是如此,但我不确定,因为我从不使用 goto。也许 @Andreas 知道,因为我见过他使用 goto!;-) - David Heffernan
1
我会怀疑GOTO语句是否能够进入finally块中...就像如果你在FOR循环中使用GOTO语句,循环计数器就不会被初始化。相比CONTINUE、BREAK和EXIT语句,GOTO语句并不那么"结构化"。 - Ken Bourassa
2
@Chris,确实,保证的是finally块将被执行,而不是它会完整运行。 - Ken Bourassa
5
刚尝试了一下:在try块中的goto会无法编译通过,这样就解决了那个替代方案。即便是在汇编块中使用JMP也无法编译通过。哇! - Rudy Velthuis

4

如果电源中断(例如,您拔掉计算机的插头并且它没有电池并且未连接到UPS),那么很可能 finally 块将不会运行。主要的操作系统或驱动程序故障(例如BSOD)也可能导致这种情况发生。然而,try..finally 结构的整个思想是,即使在 try 块内引发了任何类型的异常,finally 块也必须运行。即使在 try 块内有一个 exit 语句,finally 块也将运行。


3
@RBA:什么,确切地说?编译器无法保证主机计算机(硬件/操作系统/驱动程序)将正常运行...然而,我确实相信,如果在try内部触发了通常的raise ESomeException.Create(...)(并且没有发生其他事情,比如计算机被吸入黑洞之类的),你是可以“保证”finally块会运行的。 - Andreas Rejbrand
2
如果可以的话,我会再给“黑洞”参考一个+1。 :) - Ken White
1
请注意,当您的计算机被黑洞吸入时,由于未能完成“finally”部分而导致的内存泄漏问题相对于可能出现的其他问题来说变得微不足道。 - Chris Thornton

3

如果您的应用程序引起了DEP(数据执行预防)异常,我认为Windows将不允许您继续。您的进程将被强制退出,而无法执行最终部分。您的进程会完全“消失”。然而,这与编译器是否做了什么没有任何关系。


1

一旦进入try/finally块,无论如何,在执行离开try/finally之前,finally块都将被执行。


1
finally 块将开始执行。只希望块内部没有抛出任何异常。 - H H
1
你想给他们买一杯啤酒吗? - H H
@Henk 我经常看到的一个错误是在 finally 中放置大量代码。通常每个 finally 应该处理一个对象的释放。一旦你在 finally 块中有抛出异常的代码,你就会遇到麻烦。当然,如果发生这种情况,可能并不是世界末日。也许你并不在意。 - David Heffernan
我不会允许这样做。但是我见过很多有问题的代码,在finally中做了太多的事情。 - H H
@henk,“you”实际上是指第三人称,而不是第二人称,即“one”或法语中的“on”。我讨厌英语中的这种缺陷。或者说,我讨厌自己无法弥补这种缺陷的能力。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接