Version 1.2 of 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