Rationale for Ada 2005
7.7 Categorization of library units
It will be recalled
that library units in Ada 95 are categorized into a hierarchy by a number
of pragmas thus
pragma Pure( ... );
pragma Shared_Passive( ... );
pragma Remote_Types( ... );
pragma Remote_Call_Interface( ... );
Each category imposes restrictions on what the unit
can contain. An important rule is that a unit can only depend on units
in the same or higher categories (the bodies of the last two are not
restricted).
The pragmas Shared_Passive,
Remote_Types, and Remote_Call_Interface
concern distributed systems and thus are rather specialized. A minor
change made in the 2001 Corrigendum was that the pragma Remote_Types
was added to the package Ada.Finalization
in order to support the interchange of controlled types between partitions
in a distributed system.
Note that the pragma
Preelaborate does not fit into this hierarchy.
In fact there is another hierarchy thus
pragma Pure( ... );
pragma Preelaborate( ... );
and again we have the same rule that a unit can only
depend upon units in the same or higher category. Thus a pure unit can
only depend upon other pure units and a preelaborable unit can only depend
upon other preelaborable or pure units.
A consequence of this dual hierarchy is that a shared
passive unit cannot depend upon a preelaborable unit – the units
upon which it depends have to be pure or shared passive and so on for
the others. However, there is a separate rule that a unit which is shared
passive, remote types or RCI must itself be preelaborable and so has
to also have the pragma Preelaborate.
The categorization of individual predefined units
is intended to make them as useful as possible. The stricter the category
the more useful the unit because it can be used in more circumstances.
The categorization was unnecessarily weak in Ada
95 in some cases and some changes are made in Ada 2005.
The following packages
which had no categorization in Ada 95 have pragma Preelaborate
in Ada 2005
Ada.Asynchronous_Task_Control
Ada.Dynamic_Priorities
Ada.Exceptions
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
The following which
had pragma Preelaborate in Ada 1995 have been
promoted to pragma Pure in Ada 2005
Ada.Characters.Handling
Ada.Strings.Maps
Ada.Strings.Maps.Constants
System
System.Storage_Elements
These changes mean that certain facilities such as
the ability to analyse exceptions are now available to preelaborable
units. Note however, that Wide_Maps and Wide_Maps.Wide_Constants
stay as preelaborable because they may be implemented using access types.
Just for the record
the following packages (and functions, Hash
is a function) which are new to Ada 2005 have the pragma Pure
Ada.Assertions
Ada.Characters.Conversions
Ada.Containers
Ada.Containers.Generic_Array_Sort
Ada.Containers.Generic_Constrained_Array_Sort
Ada.Dispatching
Ada.Numerics.Generic_Real_Arrays
Ada.Numerics.Generic_Complex_Arrays
Ada.Strings.Hash
And the following new
packages and functions have the pragma Preelaborate
Ada.Containers.Doubly_Linked_Lists
Ada.Containers.Hashed_Maps
Ada.Containers.Hashed_Sets
Ada.Containers.Ordered_Maps
Ada.Containers.Ordered_Sets
Ada.Containers.Vectors
Ada.Environment_Variables
Ada.Strings.Unbounded_Hash
Ada.Strings.Wide_Wide_Maps
Ada.Strings.Wide_Wide_Maps.Wide_Wide_Constants
Ada.Tags.Generic_Dispatching_Constructor
Ada.Task_Termination
plus the indefinite containers as well.
A problem with preelaborable
units in Ada 95 is that there are restrictions on declaring default initialized
objects in a unit with the pragma Preelaborate.
For example, we cannot declare objects of a private type at the library
level in such a unit. This is foolish for consider
package P is
pragma Preelaborate(P);
X: Integer := 7;
B: Boolean := True;
end;
Clearly these declarations
can be preelaborated and so the package P
can have the pragma Preelaborate. However,
now consider
package Q is
pragma Preelaborate(Q); -- legal
type T is private;
private
type T is
record
X: Integer := 7;
B: Boolean := True;
end record;
end Q;
with Q;
package P is
pragma Preelaborate(P); -- illegal
Obj: Q.T;
end P;
The package Q is preelaborable
because it does not declare any objects. However, the package P
is not preelaborable because it declares an object of the private type
T – the theory being of course that
since the type is private we do not know that its default initial value
is static.
This
is overcome in Ada 2005 by the introduction of the pragma
Preelaborable_Initialization.
Its syntax is
pragma Preelaborable_Initialization(direct_name);
We can now write
package Q is
pragma Preelaborate(Q);
type T is private;
pragma Preelaborable_Initialization(T);
private
type T is
record
X: Integer := 7;
B: Boolean := True;
end record;
end Q;
The pragma promises that the full type will have
preelaborable initialization and the declaration of the package P
above is now legal.
The following predefined
private types which existed in Ada 95 have the pragma Preelaborable_Initialization
in Ada 2005
Ada.Exceptions.Exception_Id
Ada.Exceptions.Exception_Occurrence
Ada.Finalization.Controlled
Ada.Finalization.Limited_Controlled
Ada.Numerics.Generic_Complex_Types.Imaginary
Ada.Streams.Root_Stream_Type
Ada.Strings.Maps.Character_Mapping
Ada.Strings.Maps.Character_Set
Ada.Strings.Unbounded.Unbounded_String
Ada.Tags.Tag
Ada.Task_Identification.Task_Id
Interfaces.C.Strings.chars_ptr
System.Address
System.Storage_Pool.Root_Storage_Pool
Wide and wide-wide versions also have the pragma
as appropriate. Note that it was not possible to apply the pragma to
Ada.Strings.Bounded.Generic_Bounded_Length.Bounded_String
because it would have made it impossible to instantiate Generic_Bounded_Length
with a non-static expression for the parameter Max.
The following private
types which are new in Ada 2005 also have the pragma Preeleborable_Initialization
Ada.Containers.Vectors.Vector
Ada.Containers.Vectors.Cursor
Ada.Containers.Doubly_Linked_Lists.List
Ada.Containers.Doubly_Linked_Lists.Cursor
Ada.Containers.Hashed_Maps.Map
Ada.Containers.Hashed_Maps.Cursor
Ada.Containers.Ordered_Maps.Map
Ada.Containers.Ordered_Maps.Cursor
Ada.Containers.Hashed_Sets.Set
Ada.Containers.Hashed_Sets.Cursor
Ada.Containers.Ordered_Sets.Set
Ada.Containers.Ordered_Sets.Cursor
and similarly for the indefinite containers.
A related change concerns the definition of pure
units. In Ada 2005, pure units can now use access to subprogram and access
to object types provided that no storage pool is created.
Finally, we mention a small but important change
regarding the partition communication subsystem System.RPC.
Implementations conforming to the Distributed Systems annex are not required
to support this predefined interface if another interface would be more
appropriate – to interact with CORBA for example.
© 2005, 2006 John Barnes Informatics.
Sponsored in part by: