6

I know this was discussed on other topics also, what I'm asking is exactly the title of this question.

Is there such case when try/finally the finally won't execute?

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

I'm not talking about how try..except/finally blocks must be used, I'm just asking if this could happen.

LE: Application.Terminate/unplug your computer are particular cases.

Nicolas Kaiser
  • 1,628
  • 2
  • 14
  • 26
RBA
  • 12,337
  • 16
  • 79
  • 126
  • 3
    The compiler gives no guarantees beyond the end of the world, or your PC. Whatever comes first. But in all cases where it matters, that is when a finally block can still do something useful, it will be executed. – H H Aug 25 '11 at 14:20
  • 1
    I was looking at this question http://stackoverflow.com/questions/3484353/is-there-such-case-when-in-try-finally-block-the-finally-wont-be-executed - it seems that Java developers don't think about wormholes/end of the world/etc. I must admit that Delphi developers have the sense of humor – RBA Aug 25 '11 at 14:26

4 Answers4

22

try..finally guarantees that code in the finally block will execute regardless of any exception occuring in the protected block. This of course doesn't apply if the process is killed before the finally block can execute, e.g. by TerminateProcess or turning the power off. An endless loop in the protected block may also prevent the finally block from executing.

Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
  • 16
    A related gotcha is that not ALL of the code in the finally is guaranteed. for example, you could have 3 statements in the finally section, and you blow up on the second one. The third statement won't be executed. A good example would be trying to free objects that weren't allocated. – Chris Thornton Aug 25 '11 at 14:24
  • The guarantee is stronger. An exit, break or continue to beyond the finally will cause finally block to run. I presume the same is true for goto, but I don't know since I never use goto. Perhaps @Andreas knows since I've seen him using goto! ;-) – David Heffernan Aug 25 '11 at 16:12
  • 1
    I would doubt GOTO would pass into the finally... Just like if you GOTO into a FOR loop the loop counter isn't initialized. GOTOs aren't as "structured" as CONTINUE, BREAK and EXIT. – Ken Bourassa Aug 25 '11 at 17:14
  • 2
    @Chris, Indeed, the guarantee is that the finally block will be entered, not that it will run to completion. – Ken Bourassa Aug 25 '11 at 17:16
  • 5
    Just tried: A goto out of a try block will not compile. So that solves that alternative. Even a JMP in an asm block will not compile. Wow! – Rudy Velthuis Aug 25 '11 at 17:56
4

If the power is lost (for instance, if you unplug the computer and it has no battery and is not connected to a UPS), it is very possible that the finally block will not be run. A major OS or driver malfunction (such as a BSOD) might also cause this. However, the entire idea with the try..finally construct is that the finally block is to be run even if an exception (of any kind) is raised inside the try block. The finally block will even run if there is an exit statement inside try block.

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • 3
    @RBA: What, excatly? The compiler cannot guarantee that the host computer (hardware/OS/drivers) will function properly... However, I *do* believe that you are 'guaranteed' that the `finally` block is run if a usual `raise ESomeException.Create(...)` is hit inside `try` (and nothing else happens, like the computer is sucked into a black hole or something). – Andreas Rejbrand Aug 25 '11 at 14:13
  • 2
    +1. I'd give another +1 for the 'black hole' ref. if I could. :) – Ken White Aug 25 '11 at 14:19
  • 1
    Note that when your computer is sucked into a black hole, memory leaks caused resulting from failure to complete the "finally" section, become insignificant compared other problems that may arise. – Chris Thornton Aug 25 '11 at 14:30
3

If your app causes a DEP (Data Execution Prevention) exception, I don't think windows will allow you to continue. Your process will get whacked, without executing the finally section. Your process just "goes away". However, this has nothing to do with what the compiler did or didn't do.

Chris Thornton
  • 15,620
  • 5
  • 37
  • 62
1

Once the try/finally is entered, the finally block will execute before execution leaves the try/finally.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    The finally block will _start_ executing. Just hope nothing throws inside the block. – H H Aug 26 '11 at 10:32
  • 1
    would you like to buy them all a beer? – H H Aug 26 '11 at 11:15
  • @Henk A mistake I often see is putting lots of code in a finally. Typically each finally should dispose of one object. As soon as you have code in finally blocks that throws, you are in trouble. Of course it may not be the end of the world if that happens. Maybe you don't care. – David Heffernan Aug 26 '11 at 11:33
  • I wouldn't allow it. But I've seen a lot of dodgy code that does too much in a finally. – H H Aug 28 '11 at 19:52
  • @henk that "you" was really meant as the third person you rather than second person, i.e. one or the French on. I hate this deficiency in the English language. Or perhaps it's my inability to detect my own lack of compensation for it that I hate. – David Heffernan Aug 28 '11 at 20:05