Version 1.1 of ai05s/ai05-0130-1.txt
!standard 7.6(12) 08-12-04 AI05-0130-1/01
!standard 7.6.1(9/2)
!class binding interpretation 08-12-04
!status work item 08-12-04
!status received 08-10-17
!priority Low
!difficulty Medium
!qualifier Error
!subject Order of initialization/finalization of record extension components
!summary
!question
When a record contains two fields, one with an access discriminant and one
without, the field with the access discriminant is initialized last and
finalized first.
Does this also apply for record extensions? It would seem that the wording in
7.6(12) means that some of the components of a parent type could be required to
be initialized after the extension components. In the worst case, it could make
composition of initialization/finalization operations impossible (the operations
would have to be different for every extension in order to get the ordering right).
Is this the intent?
!recommendation
(See Summary.)
!wording
!discussion
The question is asking about an example like:
with Ada.Finalization;
package Pak1 is
type Rec0;
type Rec1 (D : access Rec0) is new
Ada.Finalization.Limited_Controlled with null record;
type Rec0 is tagged limited record
Comp1 : Rec1 (Rec0'access); --
end record;
type Rec2 is new Ada.Finalization.Limited_Controlled with null record;
procedure Initialize (X : in out Rec1);
procedure Finalize (X : in out Rec1);
procedure Initialize (X : in out Rec2);
procedure Finalize (X : in out Rec2);
type Rec4 is new Rec0 with record
Comp2 : Rec2; --
end record;
end Pak1;
with Ada.Text_IO;
package body Pak1 is
procedure Initialize (X : in out Rec1) is
begin
Ada.Text_IO.Put_Line ("Initialize Rec1");
end Initialize;
procedure Finalize (X : in out Rec1) is
begin
Ada.Text_IO.Put_Line ("Finalize Rec1");
end Finalize;
procedure Initialize (X : in out Rec2) is
begin
Ada.Text_IO.Put_Line ("Initialize Rec2");
end Initialize;
procedure Finalize (X : in out Rec2) is
begin
Ada.Text_IO.Put_Line ("Finalize Rec2");
end Finalize;
end Pak1;
with Pak1;
procedure Test1 is
X : Pak1.Rec4;
begin
null;
end Test1;
The language rules as currently constituted require that this program print:
Initialize Rec2
Initialize Rec1
Finalize Rec1
Finalize Rec2
But the reason for this requirement is in order that the Initialize operation
for a component with a self-referential access discriminant can assume that other
components of the enclosing object have already been properly initialized
(AARM 7.6(12.b)). Such a component cannot access (or even know about) components
of any extensions, so there does not appear to be any value to having this
requirement apply to all of the components of a type extension (rather than
just to the extension components alone).
This requirement surely increases the burden of understanding initialization of
a type extension, as it is not simply composing the initialization of the parent
part with the extension components.
Moreover, there is potentially an extra implementation cost here. If the implementation
uses a subprogram to initialize components of a tagged type T, it would make
sense to use that subprogram to initialize the parent components of an extension
of T (and just initialize the extension components directly in T). But that
would be complicated by this requirement, and could not be done at all in
unusual cases.
[Not sure what the right answer is here. Changing the rule could cause a subtle
incompatibility in existing programs, and not changing the rule also could
cause such an incompatibility (one presumes that this AI will spawn an appropriate
ACATS test, whatever the decision is), by causing implementers to change their
implementations to match the actual wording rather than their understanding.]
--!corrigendum 7.6.1(9/2)
!ACATS Test
An ACATS test should be constructed to test a case like the example given here,
in order to verify that the rule is implemented properly.
!appendix
!topic order of initialization/finalization of record components
!reference Ada 2005 RM 7.6(12), RM 7.6.1(9), AARM 7.6(12.b), AARM 7.6(9.a)
!from Dan Eilers 2005-10-17
!keywords initialize finalize access discriminant
!discussion
When a record contains two fields, one with an access discriminant and one
without, the field with the access discriminant is initialized last and
finalized first. The AARM explains:
7.6(12.b):
The fact that Initialize is done for components with access
discriminants after other components allows the Initialize operation
for a component with a self-referential access discriminant to assume
that other components of the enclosing object have already been
properly initialized.
7.6.1(9.a):
Reason: This allows the finalization of a component with an access
discriminant to refer to other components of the enclosing object
prior to their being finalized.
Is this rule supposed to apply even when the record is a type extension, and
the field with the access discriminant is in the ancestor part of the record?
The fields in the ancestor part should probably be initialized first and
finalized last, right?
with Ada.Finalization;
package Pak1 is
type Rec0;
type Rec1 (D : access Rec0) is new
Ada.Finalization.Limited_Controlled with null record;
type Rec0 is tagged limited record
Comp1 : Rec1 (Rec0'access); -- has access discriminant
end record;
type Rec2 is new Ada.Finalization.Limited_Controlled with null record;
procedure Initialize (X : in out Rec1);
procedure Finalize (X : in out Rec1);
procedure Initialize (X : in out Rec2);
procedure Finalize (X : in out Rec2);
type Rec4 is new Rec0 with record
Comp2 : Rec2; -- no access discriminant
end record;
end Pak1;
with Pak1;
procedure Test1 is -- related to c760012.a
X : Pak1.Rec4;
begin
null;
end Test1;
with Ada.Text_IO;
package body Pak1 is
procedure Initialize (X : in out Rec1) is
begin
Ada.Text_IO.Put_Line ("Initialize Rec1");
end Initialize;
procedure Finalize (X : in out Rec1) is
begin
Ada.Text_IO.Put_Line ("Finalize Rec1");
end Finalize;
procedure Initialize (X : in out Rec2) is
begin
Ada.Text_IO.Put_Line ("Initialize Rec2");
end Initialize;
procedure Finalize (X : in out Rec2) is
begin
Ada.Text_IO.Put_Line ("Finalize Rec2");
end Finalize;
end Pak1;
****************************************************************
Questions? Ask the ACAA Technical Agent