Version 1.1 of ai05s/ai05-0028-1.txt
!standard 10.2.1(10.1/2) 06-11-13 AI05-0028-1/01
!standard 10.2.1(11.4/2)
!standard 10.2.1(11.8/2)
!class binding interpretation 06-11-13
!status work item 06-11-13
!status received 06-10-11
!priority Medium
!difficulty Easy
!qualifier Omission
!subject Problems with preelaboration
!summary
TBD.
!question
1 - 10.2.1(10.1/2) says that any formal private type or extension is
assumed to not have preelaborable initialization. Surely this should not
apply if the formal type has a pragma Preelaborable_Initialization.
2 - The same paragraph doesn't mention formal untagged derived types, but
it seems like it should. These types may have a pragma P_I (see
10.2.1(11.8/2)) and since the actual type may have discriminants that
differ from those of the ancestor of the formal, its preelaboration
properties may differ too.
3 - I can't find a rule that would make the following illegal:
generic
type T is range <>;
package G is
pragma Preelaborate;
end;
package body G is
C : constant T := T'First;
end G;
but it seems that an instance of G where T is not a static type cannot be
preelaborable, so this case should be caught by the assume-the-worst rules
in 10.2.1(10/2-10.4/2).
4 - 10.2.1(11.4/2) says that any override of the Initialize procedure is
illegal. It would seem that an override with a null procedure should be
legal. (The AI on pragma P_I was written long before we had null
procedures.)
5 - More importantly, the property of having an override for the
Initialize procedure violates privacy, as shown by the following example:
package P is
pragma Preelaborate;
type T is new Ada.Finalization.Controlled with null record;
private
procedure Initialize (X : in out T);
end P;
It is not possible to apply pragma P_I to type P.T, so how are
preelaborable clients of P supposed to know if they can declare an object
of type P.T?
6 - In the case where pragma P_I is applied to a generic formal type
extension, it would seem reasonable to require (on the generic) that the
ancestor type have preelaborable initialization. Otherwise, we are left
with a generic that is legal but cannot be instantiated, which is
obnoxious.
!recommendation
(See Summary.)
!wording
TBD.
!discussion
Actually, all of the rules on formal parameter naming in a formal package part are
missing. We also need rules to prevent doubling, giving off non-existent parameters,
and the like.
--!corrigendum A.18.2(239/2)
!ACATS test
!appendix
From: Pascal Leroy
Date: Wednesday, October 11, 2006 3:35 AM
I am implementing the new preelaboration and purity rules in 10.2.1, and I
believe that some of the rules are incorrect or incomplete.
1 - 10.2.1(10.1/2) says that any formal private type or extension is
assumed to not have preelaborable initialization. Surely this should not
apply if the formal type has a pragma Preelaborable_Initialization.
2 - The same paragraph doesn't mention formal untagged derived types, but
it seems like it should. These types may have a pragma P_I (see
10.2.1(11.8/2)) and since the actual type may have discriminants that
differ from those of the ancestor of the formal, its preelaboration
properties may differ too.
3 - I can't find a rule that would make the following illegal:
generic
type T is range <>;
package G is
pragma Preelaborate;
end;
package body G is
C : constant T := T'First;
end G;
but it seems that an instance of G where T is not a static type cannot be
preelaborable, so this case should be caught by the assume-the-worst rules
in 10.2.1(10/2-10.4/2).
4 - 10.2.1(11.4/2) says that any override of the Initialize procedure is
illegal. It would seem that an override with a null procedure should be
legal. (The AI on pragma P_I was written long before we had null
procedures.)
5 - More importantly, the property of having an override for the
Initialize procedure violates privacy, as shown by the following example:
package P is
pragma Preelaborate;
type T is new Ada.Finalization.Controlled with null record;
private
procedure Initialize (X : in out T);
end P;
It is not possible to apply pragma P_I to type P.T, so how are
preelaborable clients of P supposed to know if they can declare an object
of type P.T?
6 - In the case where pragma P_I is applied to a generic formal type
extension, it would seem reasonable to require (on the generic) that the
ancestor type have preelaborable initialization. Otherwise, we are left
with a generic that is legal but cannot be instantiated, which is
obnoxious.
****************************************************************
From: Tucker Taft
Date: Wednesday, October 11, 2006 7:01 AM
> 2 - The same paragraph doesn't mention formal untagged derived types, but
> it seems like it should. These types may have a pragma P_I (see
> 10.2.1(11.8/2)) and since the actual type may have discriminants that
> differ from those of the ancestor of the formal, its preelaboration
> properties may differ too.
Can you give an example of this? Untagged derived types
cannot add discriminants, only effectively rename them.
Is it that the *defaults* for the discriminants can change,
and that's the issue for P_I?
****************************************************************
From: Pascal Leroy
Date: Wednesday, October 11, 2006 8:30 AM
Yes, absolutely. For instance:
type T1 (D1 : Integer := 3) is null record;
type T2 (D2 : Integer := Some_Nasty_Function) is new T1(D1=>D2);
Type T1 has obviously preelaborable initialization, and type T2 doesn't
because the creation of a default-initialized object of type T2 calls
Some_Nasty_Function.
Now consider a formal type:
generic
type Formal is new T1;
package G is
end G;
package body G is
X : Formal;
end G;
We want to reject the generic body because if G were instantiated with T2
as an actual type, the elaboration of X would call Some_Nasty_Function.
****************************************************************
From: Greg Gicca
Date: Thursday, October 12, 2006 8:40 AM
A question from the side lines...
Can T1 and T2 be in different packages?
If so how do you reject the generic since T2 may not have been compiled
(or exist) when you compile G. A bind or link time error seems unreasonable.
Maybe a novice question.
****************************************************************
From: Randy Brukardt
Date: Thursday, October 12, 2006 11:48 AM
> Can T1 and T2 be in different packages?
Yes, of course.
> If so how do you reject the generic since T2 may not have been
> compiled (or exist) when you compile G. A bind or link time
> error seems unreasonable.
Generally, in generic bodies Ada "assumes the worst". That is, if it is
*possible* for some actual to make the body illegal, then the body is
illegal even if there are many actuals that wouldn't make the body illegal.
This makes generic body sharing possible, and preserves the contract model,
among other things.
So, in this case, since it is possible for there to be a type like T2
(whether or not it actually exists), the generic body should be illegal.
Pascal's point is that we don't have such a rule, and we need one.
> Maybe a novice question.
No comment. ;-)
****************************************************************
Questions? Ask the ACAA Technical Agent