Rationale for Ada 2005

John Barnes
Table of Contents   Index   References   Search   Previous   Next 

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.

Table of Contents   Index   References   Search   Previous   Next 
© 2005, 2006 John Barnes Informatics.
Sponsored in part by:
The Ada Resource Association and its member companies: ARA Members AdaCore Polyspace Technologies Praxis Critical Systems IBM Rational Sofcheck and   Ada-Europe:
Ada-Europe