Version 1.3 of ais/ai-00161.txt
!standard 10.02.01 (09) 98-04-16 AI95-00161/01
!class confirmation 96-09-10
!status work item 98-04-16
!status received 96-09-10
!priority Medium
!difficulty Medium
!subject Default-initialized objects
!summary 98-04-16
The notion of a subtype having "preelaborable initialization" is defined by
this AI.
The creation of an object whose nominal subtype has preelaborable
initialization is allowed in a preelaborable unit.
!question 98-04-16
RM95 10.2.1(9) states that: "The creation of a default-initialized object
(including a component) of a descendant of a private type, private
extension, controlled type, task type or protected type with entry
declarations."
1. In this rule, what is the meaning of "default-initialized object"?
2. This rule seems extremely restrictive. For instance, if (as recommended)
System.Address is a private type, the declaration:
A : System.Address;
makes the enclosing unit non-preelaborable. As another example, the
implementation of Ada.Strings.Unbounded suggested in the Rationale is
impossible because the initial value for the deferred constant
Null_Unbounded_String would have to include an extension aggregate for
a controlled type, which is illegal in a preelaborable unit.
!recommendation 98-04-16
(See wording.)
!wording 98-04-16
Change the RM95 10.2.1(9) to read: "The creation of an object (including a
component) of a subtype which doesn't have preelaborable initialization.
Similarly the evaluation of an extension_aggregate with an ancestor
subtype_mark denoting such a subtype."
Add after C.4(1): "The requirements stated in this section only apply to units
which do not create objects (including components) of a descendant of a
private type, private extension, controlled type, task type or protected type;
similarly, which do not evaluate extension_aggregates with an ancestor
subtype_mark denoting a subtype of such a type."
!discussion 98-04-16
1. A "default-initialized object" is an object for which the implicit
initialization described in RM95 3.3.1(10-14) takes place. Examples of
default-initialized objects include an object_declaration without an
initialization expression, and the (anonymous) object created by the
evaluation of an extension_aggregate whose ancestor_part is a subtype
name.
Note that an object of a task type or of a protected type is always
default-initialized. Also note that for a private type or a private
extension, providing an initialization expression always requires a
reference to the name of an object, or a call to a non-static function,
which are forbidden by other rules. Finally note that for a controlled type,
an initialization expression may also be provided by an extension aggregate
(if visibility allows), which must have a controlled subtype name as the
ancestor part, which is forbidden.
The conclusion is that the phrase "default-initialized" can be removed from
RM95 10.2.1(9).
2. RM95 10.2.1(9) is indeed too restrictive. For preelaboration to be usable
(in particular in the context of distributed systems) we must loosen up the
rules dramatically. However, we do not want to impose an additional burden on
implementations which support annex C and have to comply with the requirements
of RM95 C.4. Therefore, each time we remove a restriction from RM95
10.2.1(9), we must add a corresponding restriction to RM95 C.4.
Clearly we must keep task objects and protected objects with entries in RM95
10.2.1(9). Note that the current wording seems to allow the creation of
objects of entry-less protected types, which is strange since the
component_declarations may include default_expressions which execute non-
trivial code.
In discussing private types, private extensions and controlled types, it is
useful to introduce the notion of some entities "having preelaborable
initialization."
- The partial view of a private type or private extension doesn't have
preelaborable initialization, unless it is one of the predefined types listed
below.
- Task types and protected types don't have preelaborable initialization;
controlled types which have an overriden Initialize don't have preelaborable
initialization.
- The full view of a type has preelaborable initialization if it is an
elementary type, an array type whose component subtype has preelaborable
initialization, a record type whose components all have preelaborable
initialization, a derived type whose parent type has preelaborable
initialization and (in the case of a record extension) whose components all
have preelaborable initialization.
- A record component (including a discriminant) has preelaborable
initialization if its declaration includes a default_expression whose
execution doesn't perform any of the actions listed in RM95 10.2.1(6-9), or if
its declaration doesn't include a default expression and its nominal subtype
has preelaborable initialization.
- A constrained subtype of a record type has preelaborable initialization if
all its non-discriminant components have preelaborable initialization.
- Other subtypes have preelaborable initialization if their base type has
preelaborable initialization.
- The following table lists all the private types and private extensions
declared in the predefined packages, and specify if they have preelaborable
initialization (yes) or not (no). For those packages that have a Wide_
variant, the types declared in the Wide_ variant have the same classification
as the types declared in the 'narrow' variant. The same remark applies to the
non-generic equivalents of the various generic packages.
Ada.Calendar.Time
yes
Ada.Direct_IO.File_Type no
Ada.Exceptions.Exception_Id yes
Ada.Exceptions.Exception_Occurrence yes
Ada.Finalization.Controlled yes
Ada.Finalization.Limited_Controlled yes
Ada.Numerics.Discrete_Random.Generator no
Ada.Numerics.Discrete_Random.State yes
Ada.Numerics.Float_Random.Generator no
Ada.Numerics.Float_Random.State yes
Ada.Numerics.Generic_Complex_Types.Imaginary yes
Ada.Sequential_IO.File_Type no
Ada.Streams.Root_Stream_Type yes
Ada.Streams.Stream_IO.File_Type no
Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String no
Ada.Strings.Maps.Character_Mapping no
Ada.Strings.Maps.Character_Set no
Ada.Strings.Unbounded.Unbounded_String no
Ada.Text_IO.File_Type no
Ada.Tags.Tag yes
Ada.Task_Identification.Task_Id yes
Interfaces.C.Strings.Chars_Ptr yes
System.Address yes
System.Storage_Pool.Root_Storage_Pool yes
Note: The types marked 'no' above are types for which an implementation might
want to use protected types internally to allow concurrent use of the same
object by several tasks. While this is no required by the RM, it seems that
we don't want to prevent implementations from doing this sort of things.
We plan to introduce a pragma to specify, when declaring the partial view of a
private type or private extension, that the full view has preelaborable
initialization. This will make it possible for users to declare a private
type with preelaborable initialization, without violating the privacy of
private types. This pragma will be the subject of another AI.
Having defined the notion of preelaborable initialization, we allow the
creation, in preelaborable units, of objects whose nominal subtype has
preelaborable initialization. The restrictions which used to appear in RM95
10.2.1(9) are moved to RM95 C.4.
!appendix
!section 10.2.1(9)
!subject Default-initialized objects
!reference RM95-10.2.1(9)
!from Pascal Leroy 96-08-30
!reference 96-5697.a Pascal Leroy 96-9-10>>
!discussion
The referenced paragraph says that a construct is not preelaborable if it
performs "The creation of a default-initialized object (including a component)
of a descendant of a private type, private extension, controlled type, task
type or protected type with entry declarations;"
In this rule, what is the meaning of "default-initialized object"? I couldn't
find a definition of this phrase.
Bob Duff (private communication) tells me that this phrase is intended to
cover (among other things?) an object declaration which doesn't have an
initialization expression.
Even accepting this interpretation, there remain open questions. For
instance: is an object to which a pragma Import is applied a
default-initialized object? B.1(38) and B.1(24) say that no initialization
occurs in this case, so it would seem that the answer is 'no'.
It is interesting to note that, with this interpretation, 10.2.1(9) becomes
very restrictive: for a private type, a private extension or a controlled
type, I am not sure how one could write an initial value without either
referencing the name of an object, calling a non-static function, or writing
an extension aggregate. But these things are forbidden by 10.2.1(7-9). So
10.2.1 seems to state that (except in the case of imported objects) a
preelaborable units can never declare an object of a private type, a private
extension, or a controlled type. Is it the intent?
(It looks like all objects of task or protected types are
"default-initialized", so the rule is redundant. But that's not important: it
is clear that we don't want objects of such types in preelaborated units.)
****************************************************************
From: Randy Brukardt [SMTP:Randy@rrsoftware.com]
Sent: Thursday, May 07, 1998 8:12 PM
Subject: Re: AI95-00161/02
This AI has class "Confirmation", yet proposes language which extends the
language (allowing things previously disallowed). I wouldn't expect
"Confirmation" Ais to have wording changes. Shouldn't this AI be
re-classified?
****************************************************************
From: Pascal Leroy[SMTP:phl@Rational.Com]
Sent: Friday, May 08, 1998 6:04 AM
Subject: Re: AI95-00161/02
> This AI has class "Confirmation", yet proposes language which extends the
> language (allowing things previously disallowed). I wouldn't expect
> "Confirmation" Ais to have wording changes. Shouldn't this AI be
> re-classified?
Surely it should be a binding interpretation. Thanks for noticing.
Pascal
****************************************************************
Questions? Ask the ACAA Technical Agent