CVS difference for ai05s/ai05-0027-1.txt
--- ai05s/ai05-0027-1.txt 2006/11/14 01:19:19 1.1
+++ ai05s/ai05-0027-1.txt 2006/12/16 03:13:19 1.2
@@ -1,4 +1,4 @@
-!standard A.18.2(238/2) 06-11-13 AI05-0027-1/01
+!standard A.18.2(238/2) 06-12-13 AI05-0027-1/02
!class binding interpretation 06-11-13
!status work item 06-11-13
!status received 06-11-03
@@ -23,6 +23,49 @@
!discussion
+!example
+
+Access to a finalized container can happen if a Finalize routine accesses
+a container object declared in the same master as the Finalize routine.
+This is more likely than it appears at first glance.
+
+Imagine for a moment that someone needs to instrument a controlled type to
+collect some usage information. The program might be structured like:
+
+ package Pack is
+ type T is new Ada.Finalization.Controlled with ...
+ overriding
+ procedure Finalize (Object : in out T);
+
+ type Acc_T is access all T'Class;
+ A_List : Acc_T;
+ end Pack;
+
+ package body Pack is
+ package Usage_History is new Ada.Containers.Vectors (...);
+ Finalzation_Usage: Usage_History.Vector;
+
+ procedure Finalize (Object : in out T) is
+ begin
+ -- operations on Finalization_Usage to collect data on the
+ -- finalization of objects of T.
+ end Finalize;
+ end Pack;
+
+When the program finalizes, any allocated objects remaining on A_List will be
+finalized when the finalization of the collection for type Acc_T is occurs. However,
+since finalization occurs in reverse order of declaration, the object
+Finalization_Usage will be finalized before the collection for Acc_T. So those
+finalizations will be accessing an object that is already finalized.
+
+Note that it doesn't matter where A_List is declared; it only matters where
+the access type is declared relative to the collection object. It's not unusual
+for that type to be declared visibly (this program structure is taken from the
+CLAW Windows interface library), and good Ada practice is to hide things in the
+body when possible. But doing so can easily cause finalization anomolies (see
+AI95-00280 for some examples).
+
+
--!corrigendum A.18.2(239/2)
@@ -356,6 +399,75 @@
also the case of someone calling Unchecked_Deallocation on a container,
or more realistically on an object that contains a container. But I
think if that happens outside the container package bodies, anything goes.)
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Thursday, December 14, 2006 12:31 AM
+
+Ages ago, Matt Heaney wrote:
+
+> I am curious, though, about what motivated Pascal's suggestion: under what
+> circumstances would someone be able to refer to an object that has been
+> finalized? If finalization happens immediately prior to the object being
+> destroyed, then how can someone refer to the object at all?
+
+I was working on the minutes for that AI that came out of this discussion,
+and I remembered that I wasn't convinced that it could actually happen for a
+container object (because you can't control what happens inside the
+container). So I spent a bit of time trying to figure out how it could
+happen. It turns out to be more likely than you might expect.
+
+Access to a finalized container can happen if a Finalize routine accesses a
+container object declared in the same master as the Finalize routine. How
+could that happen in real code?
+
+Imagine for a moment that someone needs to instrument a controlled type to
+collect some usage information. The program might be structured like:
+
+ package Pack is
+ type T is new Ada.Finalization.Controlled with ...
+ overriding
+ procedure Finalize (Object : in out T);
+
+ type Acc_T is access all T'Class;
+ A_List : Acc_T;
+ end Pack;
+
+ package body Pack is
+ package Usage_History is new Ada.Containers.Vectors (...);
+ Finalzation_Usage: Usage_History.Vector;
+
+ procedure Finalize (Object : in out T) is
+ begin
+ -- operations on Finalization_Usage to collect data on the
+ -- finalization of objects of T.
+ end Finalize;
+ end Pack;
+
+When the program finalizes, any allocated objects remaining on A_List will
+be finalized when the finalization of the collection for type Acc_T is
+occurs. However, since finalization occurs in reverse order of declaration,
+the object Finalization_Usage will be finalized before the collection for
+Acc_T. So those finalizations will be accessing an object that is already
+finalized. ["Finalization of the collection" for an access type is defined
+in 7.6.1(11/2).]
+
+Note that it doesn't matter where A_List is declared; it only matters where
+the access type is declared relative to the collection object. It's not
+unusual for that type to be declared visibly (this program structure is
+taken from the CLAW Windows interface library), and good Ada practice is to
+hide things in the body when possible. But doing so can easily cause
+finalization anomolies (some of the cases in AI95-00280 were originally
+encountered in CLAW).
+
+This argues strongly for at *least* the resolution decided on by the ARG in
+ABQ: Program_Error for tampering operations, bounded error (Program_Error or
+acts as empty) for operations that just read from the container.
+
+I've added this example to the otherwise empty AI, so that Tucker doesn't
+have to remember to add it when he writes it up 90 minutes before the next
+ARG meeting starts. ;-)
****************************************************************
Questions? Ask the ACAA Technical Agent