Version 1.2 of ai12s/ai12-0409-1.txt

Unformatted version of ai12s/ai12-0409-1.txt version 1.2
Other versions for file ai12s/ai12-0409-1.txt

!standard 10.2.1(11.6/2)          20-12-03 AI12-0409-1/01
!standard 10.2.1(11.7/3)
!standard 10.2.1(11.8/2)
!standard A.18.19(5/5)
!standard A.18.20(5/5)
!standard A.18.21(5/5)
!standard A.18.22(5/5)
!standard A.18.23(5/5)
!standard A.18.24(5/5)
!standard A.18.25(5/5)
!class Amendment 20-12-03
!status work item 20-12-03
!status received 20-11-27
!priority Low
!difficulty Easy
!subject Preelaborable_Initialization and bounded containers
!summary
We define a Preelaborable_Initialization attribute, which is defined only for composite types defined in the visible part of a package or a generic package, and allow the aspect definition for a nonformal type declared within a generic package to depend on the value of such an attribute.
!problem
Is it intended that a bounded container has Preelaborable_Initialization even if the actual Element_Type does not have Preelaborable_Initialization? That seems to make it impossible to store the elements directly in the container, and seems to require some sort of dynamic memory allocation (contrary to the Implementation Advice).
!proposal
[Editor's note: Argubly, this should be a Binding Interpretation, since the existing definition of the Bounded containers doesn't make any sense. But for that to work, we'd have to reclassify AI12-0399-1 as a Binding Interpretation as well (we can't modify the definition of an aspect that doesn't exist ;-). I'd suggest we split 399 in that case, as the changes to change pragmas to aspects should be part of Ada 202x presentation improvements and not some retroactive change.]
A bounded container should have Preelaborable_Initialization only if the actual Element_Type (and Key_Type for Maps) has Preelaborable_Initialization. We introduce a Preelaborable_Initialization attribute for formal composite types, and allow it to be used in the definition for the Preelaborable_Initialization aspect of a non-formal type defined within a generic.
!wording
[Author's note: This is defined as modifications to the wording introduced by AI12-0399-1.]
In place of 10.2.1(11.6/2), which was moved to Annex J, add the following:
The following attribute is defined for a nonformal composite subtype S declared within the visible part of a package or a generic package, or a generic formal private subtype or formal derived subtype.
S'Preelaborable_Initialization
This attribute is of Boolean type, and its value reflects whether the type of S has preelaborable initialization. The value of this attribute, the type-related Preelaborable_Initialization aspect, may be specified for any type for which the attribute is defined. The value shall be specified by a static expression, unless the type is not a formal type but is nevertheless declared within a generic package. In this latter case, the value may also be specified by references to the Preelaborable_Initialization attribute of one or more formal types visible at the point of the declaration of the composite type, conjoined with "and".
Modify 10.2.1(11.7/3):
[The Preelaborable_Initialization aspect shall be directly specified only for a composite type declared within the visible part of a package or a generic package. ]If the Preelaborable_Initialization aspect is specified True for a private type or a private extension, the full view of the type shall have preelaborable initialization. If the aspect is specified True for a protected type, the protected type shall not have entries, and each component of the protected type shall have preelaborable initialization. {If the aspect is specified True for a generic formal type, then in a generic_instantiation the corresponding actual type shall have preelaborable initialization. If the aspect is specified to be the conjunction of one or more Preelaborable_Initialization attribute references, then the full view of the type shall have preelaborable initialization presuming the types mentioned in the conjunction all have preelaborable initialization.} For any other composite type, the aspect shall be specified statically True or False only if it is confirming. In addition to the places where Legality Rules normally apply (see 12.3), these rules apply also in the private part of an instance of a generic unit.
Delete 10.2.1(11.8/2), which is now covered above. For reference, this paragraph was:
If the aspect is directly specified on a type declared in a generic_formal_part, then the type shall be a generic formal private type or a generic formal derived type declared in the same generic_formal_part as the pragma. In a generic_instantiation the corresponding actual type shall have preelaborable initialization.
Add after A.18.19(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization
Add after A.18.20(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization
Add after A.18.21(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization and Key_Type'Preelaborable_Initialization
Add after A.18.22(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization and Key_Type'Preelaborable_Initialization
Add after A.18.23(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization
Add after A.18.24(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization
Add after A.18.25(5/5):
* the aspect_definition for Preelaborable_Initialization is changed to:
Preelaborable_Initialization =>
Element_Type'Preelaborable_Initialization
!discussion
We debated various ways to address this issue. Although we have abandoned the use of attributes for Nonblocking and Global, we felt that for this particular aspect, allowing the use of an attribute was the simplest solution. We considered defining some additional aspect, or making some automatic rule, but none of them seemed as simple as this approach, which seemed both intuitive and readable.
!examples
See the updates to A.18.19-25 above.
!ASIS
[Not sure. Probably the attribute needs to be added to some enumeration, but I didn't check - Editor.]
!ACATS test
ACATS B- and C-Tests are needed to check that the new capabilities are supported.
!appendix

!topic Bounded containers cannot be implemented in Ada
!reference Ada 2012 RM 10.2.1 A.18.19-25
!from Jeff Carter
!discussion

I posted to comp.lang.ada:

CLA_Quote : begin

Consider the package

with Ada.Containers.Bounded_Doubly_Linked_Lists;

generic
   type E is private;
package Preelaborable is
   package EL is new Ada.Containers.Bounded_Doubly_Linked_Lists
      (Element_Type => E);
end Preelaborable;

Two Ada-12 compilers give different results on this. Compiler G accepts it 
without problem. Compiler O rejects it with the error message

preelaborable.ads: Error: line 6 col82 LRM:10.2.1(11.8/2), If a pragma 
Preelaborable_Initialization has been applied to the generic formal, the 
corresponding actual type must have preelaborable initialization

AFAICT from the ARM, the generic formal Element_Type of 
Ada.Containers.Bounded_Doubly_Linked_Lists does not have pragma 
Preelaborable_Initialization applied to it. However, the type List, which 
probably has [sub]components of Element_Type, does.

Which compiler is correct? What is the intent of the ARM?

end CLA_Quote; 
to which Randy Brukardt responded

RB_Quote : begin

I'd say both compilers are wrong, in that the RM clearly has a bug here and 
one of the implementers should have complained about it to the ARG long ago. 
:-) I'd suggest you post this question to Ada-Comment so that it gets on the 
ARG's radar.

(I'll call Preelaborable_Initialization "PI" in the following for my sanity. 
:-)

It's clear from 10.2.1 that a type with pragma PI which has components of a 
generic formal type has to have components that have a type with PI. It 
isn't possible to initialize such components without a function call, so the 
other possibility does not exist. The Bounded containers are designed such 
that there are components of the element type (more accurately, a component 
of an array of the element type). In order for there to be such a component, 
the formal type must have PI. Ergo, any body for a bounded container written 
in Ada is necessarily illegal. This is a problem that someone should have 
brought up at the ARG.

Since it is not required to write language-defined package bodies in Ada, 
one could imagine that both compilers are correct in the sense that they are 
using some non-Ada language to implement the containers. But that is is a 
fiction in the case of the containers (every implementation I know of is in 
Ada), and in any case, we intended the containers to be implementable in 
Ada. If they are not, that is a bug.

I don't know what the fix ought to be: adding PI to the formal private type 
would work, but it would reduce the usabibility of the containers in 
non-preelaborated contexts. Similarly, removing the PI from the container 
would work, but would reduce the usability of the containers in 
preelaborated contexts. Both seem pretty bad.

I'd be in favor of removing PI and Preelaboration in general from the 
language (it serves no purpose other than to encourage implementers to make 
optimizations that they should make anyway - the other intentions don't work 
or are better handled with other mechanisms), but I doubt that I'd get any 
support for that.

end RB_Quote;

My initial thought when encountering this was that leaving PI on the container 
was an oversight. 

****************************************************************

From: Tucker Taft
Sent: Friday, November 27, 2020  7:50 AM

One reasonable interpretation is that the lists should have preelaborable 
initialization if and only if the element type has P.I.  I don't know how to 
express this in existing Ada, but that seems like the best answer and could be 
described in English, with some future pragma used to enforce it.

****************************************************************

From: Tucker Taft
Sent: Friday, November 27, 2020  8:32 AM

I suppose one could implement this as follows, even if Element_Type did *not* 
have preelaborable initialization:

    type Element_Array is array (Count_Type range <>) of Element_Type;

    type Inner_List (Capacity : Count_Type := 0) is record
         Data : Element_Array (Capacity);
   end record;

    type List (Capacity : Count_Type) is tagged record
         Length : Count_Type := 0;
         Inner : Inner_List;  --  Defaults to Capacity = 0
    end record;

And then the first update to such a list which added any elements could do a 
full-object assignment to "Inner":

     procedure Append (Container : in out List; New_Item : Element_Type) is
     begin
         if Container.Inner.Capacity = 0 then
               --  Initialize the inner object by full-record assignment
               Container.Inner := (Capacity => Container.Capacity, Data => (others => <>));
         end if;
         pragma Assert (Container.Inner.Capacity = Container.Capacity);
         ...
    end Append;

This means that there are no subcomponents of type Element_Type in a 
default-initialized object of type List, so it doesn't matter whether 
Element_Type has preelaborable initialization.

****************************************************************

From: Randy Brukardt
Sent: Friday, November 27, 2020  9:38 PM

I don't think this works, at least not without a lot of language and compiler 
surgery:

First of all, PI requires that all of the subcomponents are either 
default-initialized or have a type with PI. Neither of these are true for your 
Inner_List type. Moreover, there's nothing in the PI rules allowing one to 
ignore "discriminant-dependent components" in any case. Since a compiler will
presumably need to use special code generation for types with PI (at least to
avoid some possibilities), it seems that it would be very painful to support 
such a cut-out.

Secondly, most compilers use an allocate-the-max strategy for types with 
defaulted discriminants. Since Count_Type is typically implemented to put the 
minimal limits on containers, Count_Type'Last is usually at least 2**32.
As such, any object of type Inner_List is going to use a massive amount of 
memory. You want to have the (outer) object's discriminant determine the 
amount of memory to allocate, not some later dynamically determined 
discriminant.

An implementation that uses some form of dynamic allocation for types like 
Inner_List (those with defaulted discriminants) could use this format, but 
that would completely defeat the purpose of the bounded containers in 
avoiding dynamic allocation.

So I don't think this way leads anywhere.

****************************************************************

From: Tucker Taft
Sent: Friday, November 27, 2020  10:55 AM

> First of all, PI requires that all of the subcomponents are either 
> default-initialized or have a type with PI. Neither of these are true 
> for your Inner_List type. Moreover, there's nothing in the PI rules 
> allowing one to ignore "discriminant-dependent components" in any 
> case. Since a compiler will presumably need to use special code 
> generation for types with PI (at least to avoid some possibilities), 
> it seems that it would be very painful to support such a cut-out.

I think this could be fixed with:

     type List (Capacity : Count_Type) is tagged record
        Length : Count_Type := 0;
        Inner : Inner_List := (Capacity => 0, Data => (others => <>));
    end record;

> Secondly, most compilers use an allocate-the-max strategy for types 
> with defaulted discriminants. Since Count_Type is typically 
> implemented to put the minimal limits on containers, Count_Type'Last is
> usually at least 2**32.
> As such, any object of type Inner_List is going to use a massive 
> amount of memory. You want to have the (outer) object's discriminant 
> determine the amount of memory to allocate, not some later dynamically 
> determined discriminant.

Presumably we could pick some reasonable upper bound.

****************************************************************

From: Randy Brukardt
Sent: Saturday, November 28, 2020  8:10 PM

> Presumably we could pick some reasonable upper bound.

I don't see how. Element sizes can vary wildly (from a single pointer to 
an array of thousands of records). There would either be massive amounts of
waste (beyond that already implied by the design of the bounded container),
or the limit would be too small for some uses (thousands of elements can 
occur in some containers).

Arbitrary limits are always a problem, sooner or later.

****************************************************************

From: Tucker Taft
Sent: Saturday, November 28, 2020  8:54 PM

Agreed.  Not really a solution -- it was more of an exercise.

****************************************************************

From: Randy Brukardt
Sent: Friday, November 27, 2020  9:57 PM

> One reasonable interpretation is that the lists should have 
> preelaborable initialization if and only if the element type has P.I.

That would be a reasonable goal, but that's not what the language currently 
says.

It certainly would make sense for most generics to work this way, since it 
doesn't make a lot of sense to declare objects to have PI if they have parts
that don't have PI.

> I don't know how to express this in existing Ada, but that seems like 
> the best answer and could be described in English, with some future 
> pragma used to enforce it.

I don't think we should start trying to describe basic functionality in 
English -- it's the wrong direction.

I think it would make the most sense to define a new aspect related to 
Preelaborable_Initialization for this case. Brainstorming on this a bit, I 
think we might want to use the Use_Formal mechanism along with this.

So, presenting a barely-thought-out proposal:

For a type for which aspect Preelaborable_Initialization can be specified and 
which is declared in a generic specification, the following aspect can be 
specified:

   Generic_Preelaborable_Initialization  The type of this aspect is Boolean 
   and shall be specified with a static expression.

   When True, enforces preelaborable initialization restrictions on the 
   associated type has preelaborable initialization assuming that all formal
   types of the generic unit (or those given in an Use_Formal clause on the 
   same type declaration) have preelaborable initialization.

   When True, in an instance, the associated type has preelaborable 
   initialization if and only all of the actual types for the formal types 
   of the generic unit (or those given in an Use_Formal clause on the same 
   type declaration) have preelaborable initialization.

   When False, the type does not have preelaborable initialization.

---

An alternative would be to revise the existing (but just added) 
Preelaborable_Initialization aspect to work this way; that would requiring 
adding Use_Formal => null to existing predefined preelaborated generic units 
other than the bounded containers. (Note that the unbounded and indefinite 
containers do not have this problem, as the elements aren't allocated until
they are inserted.) I'm a bit concerned that people might change pragma PI 
into aspect PI without noting this difference. It would reduce the amount of
complication, but I worry that the case where the private type in the generic
unit doesn't have any parts of the formal types (or at least any parts that 
need PI) is too common to require a two-part declaration for it.

---

A different alternative would be to have the aspect take a list of formal 
types rather than using the Use_Formal mechanism. That seems more complex 
to define, since we'd have to invent some list syntax and add a bunch of 
rules about the resolution of them. Use_Formal already does this, and I'd 
think that much of the time, you would want all (or none) of the formal types
involved anyway.

---

Thoughts???

****************************************************************

From: Tucker Taft
Sent: Saturday, November 28, 2020  7:30 AM

My goal would be to keep things as simple as possible, but still solve this
problem. ;-)

If we believe the only problem is the bounded containers, then it would be 
nice if the solution only required a change to them.  On the other hand, if 
you go to the trouble of specifying an aspect with a name as long as 
"Preelaborable_initialization" then perhaps expecting a bit more is not 
unreasonable.

Unfortunately, Use_Formal is an Annex H feature, and is clearly oriented 
toward Global and Nonblocking, so allowing its use for 
Preelaborable_Initialization is bound to add complexity, since that aspect 
is in the "core" of the standard.

An alternative not mentioned was to define an attribute 
'Preelaborable_Initialization, and allow the specification of the 
Preelaborable_Initialization aspect of a type declared within a generic to 
refer to the Preelaborable_Initialization of a generic formal type.  We have 
had trouble with this in the past for the use of 'Nonblocking and 'Global, but
this seems like a simpler situation.

****************************************************************

From: Randy Brukardt
Sent: Saturday, November 28, 2020  8:03 PM

...
> An alternative not mentioned was to define an attribute 
> 'Preelaborable_Initialization, and allow the specification of the 
> Preelaborable_Initialization aspect of a type declared within a 
> generic to refer to the Preelaborable_Initialization of a generic 
> formal type.  We have had trouble with this in the past for the use of 
> 'Nonblocking and 'Global, but this seems like a simpler situation.

I rejected that solution simply because it was rejected for Nonblocking. And 
there the problem was mainly with the rules for nested generics (which meant 
that the aspect was no longer a simple Boolean aspect, but rather was based 
on expressions). We'd still have that sort of issue here.

I'd rather have a general solution if at all possible, because users ought to 
be able to write their own containers. The less "magic" we have to use the 
better. And we spent quite a bit of effort on formal incomplete types, 
generalized indexing, and generalized references just to avoid using magic
in the containers -- it would be sad to introduce some at this late point 
(and with something that's quite a bit easier).

I suppose we could split the baby and not worry about cases where more than 
one generic formal is involved (we don't need that for the bounded containers;
it's just bad language design to only allow one of something, but some iffy 
design is OK if we don't expect this to be used much outside of the 
containers). That would simplify the definition of the 
Generic_Preelaborable_Initialization aspect to be a single name that has to be 
of a formal type of an enclosing generic unit.

****************************************************************

From: Tucker Taft
Sent: Saturday, November 28, 2020  8:53 PM

> ...
>> An alternative not mentioned was to define an attribute 
>> 'Preelaborable_Initialization, and allow the specification of the 
>> Preelaborable_Initialization aspect of a type declared within a 
>> generic to refer to the Preelaborable_Initialization of a generic 
>> formal type.  We have had trouble with this in the past for the use 
>> of 'Nonblocking and 'Global, but this seems like a simpler situation.
> 
> I rejected that solution simply because it was rejected for 
> Nonblocking. And there the problem was mainly with the rules for 
> nested generics (which meant that the aspect was no longer a simple 
> Boolean aspect, but rather was based on expressions). We'd still have that
> sort of issue here.

Could you give an example?  My hope was that it wouldn't suffer from the 
complexity of 'Nonblocking.

> I'd rather have a general solution if at all possible, because users 
> ought to be able to write their own containers. The less "magic" we 
> have to use the better. And we spent quite a bit of effort on formal 
> incomplete types, generalized indexing, and generalized references 
> just to avoid using magic in the containers -- it would be sad to 
> introduce some at this late point (and with something that's quite a bit easier).

I agree we don't want a "magic" solution -- I don't think the 
'Preelaborable_Initialization attribute is magic.  Which of the solutions we 
discussed uses "magic"?
 
> I suppose we could split the baby and not worry about cases where more 
> than one generic formal is involved (we don't need that for the 
> bounded containers; it's just bad language design to only allow one of 
> something, but some iffy design is OK if we don't expect this to be 
> used much outside of the containers). That would simplify the 
> definition of the Generic_Preelaborable_Initialization aspect to be a 
> single name that has to be of a formal type of an enclosing generic unit.

I would rather not introduce another aspect if we can avoid it.

****************************************************************

From: Randy Brukardt
Sent: Sunday, November 29, 2020  1:17 AM

> > I rejected that solution simply because it was rejected for 
> > Nonblocking. And there the problem was mainly with the rules for 
> > nested generics (which meant that the aspect was no longer a simple 
> > Boolean aspect, but rather was based on expressions). We'd still 
> > have that sort of issue here.
> 
> Could you give an example?  My hope was that it wouldn't suffer from 
> the complexity of 'Nonblocking.

It would, because the aspect would have to be an expression, rather than a 
Boolean value. Inside of a generic, one does not have a known value for 
<Formal_Type>'Preelaborable_Initialization. So that would mean that one would
need all of the handwaving about expressions that evaluate to a static value 
that was the real problem with 'Nonblocking. (Yes, the rules in the generic 
body were fairly complex, but they did the right thing -- no one would have 
to understand them. The stuff about static expressions and nonstatic 
expressions was pervasive -- when you changed back to a pure Boolean model 
you changed 50% of the wording -- and most of what you didn't change probably
should have been changed too.) If you tried to avoid that handwaving, it 
wouldn't be possible to make the needed P_I checks (or more accurately, *not*
make the checks in specific cases).

I can give some examples on Monday; it's too late tonight (time to go home - 
I've been Christmas shopping [on-line] tonight).

> I would rather not introduce another aspect if we can avoid it.

Trying to use one aspect would be way more complex than using two with 
targetted rules. The only way to do that makes sense to me would be piggyback 
on Use_Formal, which you said you didn't want to do.

****************************************************************

From: Tucker Taft
Sent: Monday, November 30, 2020  9:26 AM

> It would, because the aspect would have to be an expression, rather than a
> Boolean value. Inside of a generic, one does not have a known value for
> <Formal_Type>'Preelaborable_Initialization. So that would mean that one
> would need all of the handwaving about expressions that evaluate to a static
> value that was the real problem with 'Nonblocking. (Yes, the rules in the
> generic body were fairly complex, but they did the right thing -- no one
> would have to understand them. The stuff about static expressions and
> nonstatic expressions was pervasive -- when you changed back to a pure
> Boolean model you changed 50% of the wording -- and most of what you didn't
> change probably should have been changed too.) If you tried to avoid that
> handwaving, it wouldn't be possible to make the needed P_I checks (or more
> accurately, *not* make the checks in specific cases).

I think it is a bit simpler because P_I is only permitted on composite types, 
and the attribute would only be defined on formal private types/extensions.  
Therefore we could restrict the definition of the P_I aspect to either False, 
True, or "formal'P_I and formal'P_I and formal'P_I and ...".  Nothing more 
complex than that would be needed, I believe.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, December 1, 2020  12:17 AM

Sure, but the expensive part is changing the aspect from a static Boolean 
value to something else to allow the expression (whatever form it would have).
As I noted yesterday, we'd have to change just about every reference to the 
aspect in the RM text, as it would have to be an expression-valued aspect. 
And then there would have to be the nasty hand-waving about when the 
expression has a static value. (At least if we followed the old model of 
Nonblocking. That was never very satisfactory.)

The complications to the P_I rules themselves is not a real concern here -- 
especially as we could simply treat any named formal types as if they have 
P_I. It's the changes needed to support an expression-valued aspect when one
cannot assume that you have a static expression.

BTW, one has to support static boolean expressions, not just the literals True
and False. There are a number of plausable uses for a global Boolean constant 
rather than using a literal. (Presumably, one would use the constant both for 
the package Preelaborate and any Preelaborable_Initializations.) It would be 
nasty to be able to use a named constant for Preelaborate but not be able to 
do that for Preelaborable_Initialization.

****************************************************************

From: Tucker Taft
Sent: Tuesday, December 1, 2020  6:58 AM

Unlike "nonblocking," the term "preelaborable initialization" appears 
extremely rarely in the normative wording of the reference manual.  In 
particular, I believe that it appears in exactly three places -- 10.2.1,
13.7, and the index.  Of course an aspect definition for 
Preelaborable_Initialization appears in many places, but that seems irrelevant 
to this situation.  We will only be changing that for bounded containers, and 
we have to make some change for bounded containers if we are going to fix this
problem.

I would suggest that I write up an AI with the wording changes for this 
approach, and see how bad it looks.

****************************************************************

From: Randy Brukardt
Sent: Thursday, December 3, 2020  9:40 PM

[This is relative to draft /01 of the AI - Editor.]

I had a number of comments on the draft of AI12-0409-1 that will be on the 
agenda; since Tucker does not plan to address any of them before the agenda 
is posted I'm putting them here for the record (so we can discuss them at the
meeting or here). The full AI will go up with the agenda tonight.

---


!wording
> [Author's note: This is defined as modifications to the wording 
> introduced by AI12-0399-1.]

It's rather hard to evaluate this wording without the other wording (which 
will not be in draft 27, either, as I didn't want to do all of that work 
twice).

Note that AI12-0399-1 is an Amendment, so an AI modifying it cannot be a 
Binding Interpretation. Since this problem really needs a fix for Ada 2012, we 
probably need to move the aspect wording from that AI to this one (leaving the 
library changes from pragma to aspect).

> In place of 10.2.1(11.6/2), which was moved to Annex J, add the
> following:
> 
>   The following attribute is defined for a nonformal composite subtype S
>   declared within the visible part of a package or a generic package, or
>   a generic formal private subtype or formal derived subtype.
> 
>   S'Preelaborable_Initialization
>   
>     This attribute is of Boolean type, and its value reflects whether
>     the type of S has preelaborable initialization. The value of this
>     attribute, the type-related Preelaborable_Initialization aspect, may
>     be specified for any type for which the attribute is defined. The
>     value shall be specified by a static expression, unless the type is
>     not a formal type but is nevertheless declared within a generic
>     package.  In this latter case, the value may also be specified by
>     references to the Preelaborable_Initialization attribute of one or
>     more formal types visible at the point of the declaration of the
>     composite type, conjoined with "and".

(1) Do we really want to introduce a new specifiable attribute (which implies 
that attribute_definition_clauses need to be supported)? Nonblocking defined 
attributes, but only allow specification of aspects.

(2) Why the restriction to "not a formal type"? It seems like a nested generic 
of a type similar to the containers might need to depend on an outer formal 
type. Perhaps this is OK if we agree that this is a hack rather than a 
well-defined feature. (The same goes for the inability to combine a static
expression with some aspects.)

(3) Does this work right if a generic used in a formal package uses this 
aspect? Shouldn't it be possible to depend on the P_I attribute of (some 
formal type of) a formal package parameter?

> Modify 10.2.1(11.7/3):
> 
>   [The Preelaborable_Initialization aspect shall be directly specified
>   only for a composite type declared within the visible part of a
>   package or a generic package.  ]If the Preelaborable_Initialization
>   aspect is specified True for a private type or a private extension,
>   the full view of the type shall have preelaborable initialization. If
>   the aspect is specified True for a protected type, the protected type
>   shall not have entries, and each component of the protected type shall
>   have preelaborable initialization. {If the aspect is specified True
>   for a generic formal type, then in a generic_instantiation the
>   corresponding actual type shall have preelaborable initialization. If
>   the aspect is specified to be the conjunction of one or more
>   Preelaborable_Initialization attribute references, then the full view
>   of the type shall have preelaborable initialization presuming the
>   types mentioned in the conjunction all have preelaborable
>   initialization.} ...

We haven't used the word "conjunction" before in the Standard, just saying an 
"and" of things. Seems kinda late to introduce such a term.

Additionally, the phrase "the types mentioned in the conjunction" seems too 
handwavy to me. Something like "the types mentioned in the prefixes of the 
"and"ed Preelaborable_Initialization attribute references" would be clearer 
and avoid introducing the first use of conjunction in the Standard. 

>   ... For any other composite type, the aspect shall be
>   specified statically True or False only if it is confirming. In
>   addition to the places where Legality Rules normally apply (see 12.3),
>   these rules apply also in the private part of an instance of a generic
>   unit.

Is it clear from the other wording (which I don't have in front of me) that 
the *aspect* value is determined by whether or not a type is defined to have 
preelaborable initialization? I know that whether a type has preelaborable 
initialization is well defined for most types, but that doesn't say anything 
about the aspect value. I fear that the definition could very well be circular
(the aspect depends on whether the type has preelaborable initialization, and 
the type has preelaborable initialization if the aspect is True; if both of 
these things are defined, then it is impossible for the aspect to be 
confirming, as the specification of it has already changed the value).

---

How does this aspect relate to the rules for Boolean-valued aspects? In 
particular, if the value is not a statically known Boolean-value, how can one 
enforce 13.1.1(18.1/4)?? Are you assuming a re-check in specs? What about 
generic bodies?? (In case you missed what I'm driving at, you cannot know at 
generic unit compile-time what the value for the parent type is. So how do you 
know if the rule applies?)

****************************************************************

Questions? Ask the ACAA Technical Agent