I'm a bit rusty so I don't see what I'm doing wrong here.

I'm a bit rusty so I don't see what I'm doing wrong here.

I'm having some issues where the finalization order seems to depend on Application.Run being executed or not.

In my setup, Unit1 uses Unit2 in the interface section. Unit1 contains a form which accesses a global pointer variable in Unit2 in the OnDestroy handler.

Unit2 has an initialization and finalization section, and it nils the pointer in the finalization section.

Now, by default, this works fine. However if I do not call Application.Run in the DPR file, then the finalization section in Unit2 is called before the form is destroyed.

Sample code is here, add/remove a command line parameter to trigger the error. Alternatively just comment out Application.Run.
https://www.dropbox.com/s/ky3ob758xofer1f/FinalizationError.zip

In my real-world case, the "Unit2" is actually Data.SqlTimSt, and the global variable is it's internal SQLTimeStampVariantType variable, which is used indirectly through Data.DB, which my form uses. In my form's OnDestroy I do an SQL update involving a DateTime.

I've tested this on XE3 and XE5.
https://www.dropbox.com/s/ky3ob758xofer1f/FinalizationError.zip

Comments

  1. I believe that finalization order is never guaranteed and can change at any time.

    ReplyDelete
  2. For the units that have an init section, will not the finalization be in the opposite order of the init, Nick Hodges ?

    ReplyDelete
  3. I think I know what's going on now. By placing Unit2 above Forms in the DPR uses section, it's guaranteed to be initialized before, and thus finalized after, the Forms unit. This means TApplication does its shutdown before Unit2 is finalized always.

    Before the code strictly shouldn't work, as Unit2 should always be finalized before TApplication does it shutdown. Why Application.Run changes that behavior I don't know, perhaps because of the way the IDE adds units to the uses section?

    ReplyDelete
  4. Lars  -- My understanding, if I recall correctly, is that initialization and finalization order is non-deterministic and one should not code such that one depends on that order.

    ReplyDelete

Post a Comment