Version 1.2 of ais/ai-00362.txt

Unformatted version of ais/ai-00362.txt version 1.2
Other versions for file ais/ai-00362.txt

!standard 03.09(06)          03-11-26 AI95-00362/01
!standard 11.04.01(02)
!standard 11.04.01(03)
!standard A.03.02(02)
!standard A.08.01(02)
!standard A.08.04(02)
!standard C.07.01(02)
!standard D.05(03)
!standard D.10(03)
!standard D.11(03)
!class amendment 03-11-26
!status work item 03-11-26
!status received 03-10-04
!priority Medium
!difficulty Medium
!subject Some predefined packages should be preelaborated
!summary
Some predefined packages have categorization added or strengthened.
!problem
Predefined Ada packages should be categorized as restrictively as possible, in order for them to be as widely applicable as possible. AI-161 provides a mechanism to allow more packages to be preelaborated. All Ada 95 packages should be checked to insure that they are categorized correctly.
!proposal
[Editor's meta note: I've been fairly aggressive about proposing changes here. In many cases, I'm not very certain of the conclusions, so discussion is welcome.]
Ada.Asynchronous_Task_Control is declared preelaborated. Ada.Characters.Handlers is declared pure. Ada.Direct_IO is declared preelaborated. Ada.Dynamic_Priorities is declared preelaborated. Ada.Exceptions is declared preelaborated. Ada.Sequential_IO is declared preelaborated. Ada.Streams.Stream_IO is declared preelaborated. Ada.Synchronous_Task_Control is declared preelaborated. Ada.Tags is declared preelaborated. Ada.Task_Identification is declared preelaborated.
!wording
Change 3.9(6) to
package Ada.Tags is pragma Preelaborate(Tags); type Tag is private;
Change 11.4.1(2) to
package Ada.Exceptions is pragma Preelaborate(Exceptions); type Exception_Id is private; pragma Preelaboratable_Initialization (Exception_Id); Null_Id : constant Exception_Id; function Exception_Name(Id : Exception_Id) return String;
Change 11.4.1(3) to
type Exception_Occurrence is limited private; pragma Preelaboratable_Initialization (Exception_Occurrence); type Exception_Occurrence_Access is access all Exception_Occurrence; Null_Occurrence : constant Exception_Occurrence;
Change A.3.2(2) to
package Ada.Characters.Handling is pragma Pure(Handling);
Add after A.8.1(2):
pragma Preelaborate(Sequential_IO);
Add after A.8.4(2):
pragma Preelaborate(Direct_IO);
Change C.7.1(2) to
package Ada.Task_Identification is pragma Preelaborate(Task_Identification); type Task_ID is private; pragma Preelaboratable_Initialization (Task_Id); Null_Task_ID : constant Task_ID; function "=" (Left, Right : Task_ID) return Boolean;
Change D.5(3) to
with System; with Ada.Task_Identification; package Ada.Dynamic_Priorities is pragma Preelaborate(Dynamic_Priorities);
Change D.10(3) to
package Ada.Synchronous_Task_Control is pragma Preelaborate(Synchronous_Task_Control);
Change the head of D.11(3) to
package Ada.Asynchronous_Task_Control is pragma Preelaborate(Asynchronous_Task_Control);
!discussion
Here we list all Ada 95 predefined packages and their standard categorization. (We do not consider Annex E categorization here; AI-126 did that, and there are not any proposed changes that would change the results of that AI.) Packages that are not already either pure or preelaborated are examined to see whether they should be given pragma Preelaborate; packages that are preelaborated are examined to see whether they should be given pragma Pure. The run-time implementation of two compilers (GNAT and Janus/Ada) also are examined for impacts of any proposed change.
Remember that any dependencies of a Pure unit must be Pure and any dependencies of a Preelaboratable unit must be Pure or Preelaboratable.
[Editor's meta comment: Many of the arguments for not declaring a package Preelaboratable depend on the need to initialize complex state at elaboration time. It should be noted that it is always possible to work around such requirements -- simply keep a boolean flag as to whether the state is initialized; and check that flag on each call that needs the state. If the state needs initialization, call the initialization routine (and set the flag) before using the state.
I did not assume the use of this technique for several reasons: (1) there is a (small) cost on every call to check if the package is properly initialized; (2) there is a (small) code overhead with each routine that needs the additional checks; (3) using such a technique could require massive restructuring of the existing RTS (because the existing implementations may depend on other packages which also would have to be made preelaborated.
Packages with a small number of routines that need to access the state could be reconsidered with the expectation that this technique would be used; Ada.Calendar and Ada.Real_Time are examples of packages where few operations need state.]
Standard -- A.1; Pure Ada -- A.2; Pure Ada.Asynchronous_Task_Control -- D.11; not categorized.
This package depends on Ada.Task_Identification, so it cannot be pure. This package is really an interface to the tasking runtime, and any state needed is there. There should be no need for any separate initialization. The task runtime must be able to be called from a pure package (it is perfectly possible to declare or rendezvous with a task in a pure package). Thus, this package should be Preelaborated.
Ada.Calendar -- 9.6; not categorized.
Some systems implement Clock by determining the difference between an initial time and the current time. Getting the initial time requires (system) subprogram calls during elaboration, which is not allowed in a preelaboratable unit.
For example, many Windows implementations use a combination of the system time function and the high performance counter to provide decent precision for Clock. The high performance counter is just a 64-bit counter for which the elapsed time is the difference between two values. For this, an initial value must be saved. Both the GNAT and Janus/Ada implementations use this technique. Thus, making the package Preelaborated could cause an intolerable performance incompatibility.
[Note: If this decision is reversed, Float_Random and Discrete_Random also should be made Preelaborated, the latter only if A.5.2(39) is also changed.]
Ada.Characters -- A.3.1; Pure Ada.Characters.Handling -- A.3.2; Preelaborate
This package contains no state, no dependence on non-pure units, no items that prevent the package from being pure, and does not declare any types (so there is no problem with Annex E). The only possible reason for not declaring this pure is so that it can be implemented by using Ada.Strings.Maps. But this routine isn't complex enough for that to be any real benefit. This package should be declared pure.
GNAT's implementation does with and use Ada.Strings.Maps, but does not appear to actually reference it anywhere. Janus/Ada's implementation does not depend on any other package.
Ada.Characters.Latin_1 -- A.3.3; Pure Ada.Command_Line -- A.15; Preelaborate
This package has state -- the program's command line -- and thus cannot be pure.
Ada.Decimal -- F.2; Pure Ada.Direct_IO -- A.8.4; not categorized.
Any state that the operations need should be contained in the File_Type object; separate state is not needed. Howover, most Ada implementations have some sort of file cleanup (to deal with files left open by the program). That cleanup would require some state (typically a controlled object). That object is was allowed in a preelaborated package in Ada 95, but such types are allowed by AI-161 (as Controlled and Limited_Controlled have preelaboratable initialization). Therefore, this package should be Preelaborated.
GNAT uses a controlled object to clean up files in a package used by Direct_IO. There is no other state in any of the packages. Janus/Ada uses a small amount of state in a package used by Direct_IO, this could be moved to Open/Create. There is no other state.
Ada.Dynamic_Priorities -- D.5; not categorized
This package depends on Ada.Task_Identification, so it cannot be pure. This package is really an interface to the tasking runtime, and any state needed is there. There should be no need for any separate initialization. The task runtime must be able to be called from a pure package (it is perfectly possible to declare or rendezvous with a task in a pure package). Thus, this package should be Preelaborated.
Ada.Exceptions -- 11.4.1; not categorized
The package cannot be pure because it contains named access types. The package Ada.Exceptions was not preelaborated in Ada 95 because of the default initialized objects Null_Id and Null_Occurrence. With appropriate use of pragma Preelaboratable_Initialization, this limitation can be eliminated. The package has no state of its own, and the routines it depends upon must be able to be called from a pure package (it is perfectly possible to raise and handle an exception in a pure package). Thus, this package should be Preelaborated.
GNAT's implementation uses a lot of dependencies and state; dunno if this change would be difficult to implement. Janus/Ada uses a 'built-in' implementation of this package, thus the categorization has no impact on the implementation.
Ada.Finalization -- 7.6; Preelaborate Ada.Float_Text_IO -- A.10.9; not categorized
Depends on Ada.Text_IO; see that unit for discussion.
Ada.Float_Wide_Text_IO -- A.11; not categorized
Depends on Ada.Wide_Text_IO; see that unit for discussion.
Ada.Integer_Text_IO -- A.10.8; not categorized
Depends on Ada.Text_IO; see that unit for discussion.
Ada.Integer_Wide_Text_IO -- A.11; not categorized Ada.Interrupts -- C.3.2; not categorized
This package depends on System, so it cannot be pure. This package may need to execute code and/or system calls to gather the initial state (the default handlers) of interrupts. Thus, the package cannot be preelaborated.
Ada.Interrupts.Names -- C.3.2; not categorized
Depends on Ada.Interrupts; see the discussion of that unit.
Ada.IO_Exceptions -- A.13; Pure Ada.Numerics -- A.5; Pure Ada.Numerics.Complex_Elementary_Functions -- G.1.2; Pure Ada.Numerics.Complex_Types -- G.1.1; Pure Ada.Numerics.Discrete_Random -- A.5.2; not categorized
The AARM notes that this cannot be pure, because the private part will require an access type. All of the state should be implemented in the generator object, so no initialization should be needed at elaboration time. However, the implementation does have to depend on Ada.Calendar (or an equivalent) to implement the one parameter Reset. Thus, since Calendar is not preelaborated, neither can this package be preelaborated. Moreover, the rule of A.5.2(39) requires execution of a statement at instantiation elaboration time.
Neither GNAT nor Janus/Ada have any state here; both depend on Ada.Calendar. Janus/Ada does execute some code at elaboration time to implement A.5.2(39); GNAT makes this check on each call to Random (which doesn't correctly implement A.5.2(39)).
Ada.Numerics.Elementary_Functions -- A.5.1 Ada.Numerics.Float_Random -- A.5.2; not categorized
The AARM notes that this cannot be pure, because the private part will require an access type. All of the state should be implemented in the generator object, so no initialization should be needed at elaboration time. However, the implementation does have to depend on Ada.Calendar (or an equivalent) to implement the one parameter Reset. Thus, since Calendar is not preelaborated, neither can this package be preelaborated.
Neither GNAT nor Janus/Ada have any state here; both depend on Ada.Calendar.
Ada.Numerics.Generic_Complex_Elementary_Functions -- G.1.2; Pure Ada.Numerics.Generic_Complex_Types -- G.1.1; Pure Ada.Numerics.Generic_Elementary_Functions -- A.5.1; Pure Ada.Real_Time -- D.8; not categorized
The implementation of this package is similar to Ada.Calendar, see that package's discussion.
Ada.Sequential_IO -- A.8.1; not categorized
Any state that the operations need should be contained in the File_Type object; separate state is not needed. But see the discussion of Direct_IO; the same cleanup is used here. Still, this package should be Preelaborated.
GNAT uses a controlled object to clean up files in a package used by Sequential_IO. There is no other state in any of the packages. Janus/Ada uses a small amount of state in a package used by Sequential_IO, this could be moved to Open/Create. There is no other state.
Ada.Storage_IO -- A.9; Preelaborate Ada.Streams -- 13.13.1; Pure Ada.Streams.Stream_IO -- A.12.1; not categorized
This package contains a named access type, so it cannot be pure. Any state that the operations need should be contained in the File_Type object; separate state is not needed. But see the discussion of Direct_IO; the same cleanup is used here. Still, this package should be Preelaborated.
GNAT uses a controlled object to clean up files in a package used by Stream_IO. There is no other state in any of the packages. Janus/Ada uses a small amount of state in a package used by Stream_IO, this could be moved to Open/Create. There is no other state.
Ada.Strings -- A.4.1; Pure Ada.Strings.Bounded -- A.4.4; Preelaborate
Depends on Ada.Strings.Maps, see that package's discussion.
Ada.Strings.Fixed -- A.4.3; Preelaborate
Depends on Ada.Strings.Maps, see that package's discussion.
Ada.Strings.Maps -- A.4.2; Preelaborate
This package contains a named access type, and thus cannot be pure.
Ada.Strings.Maps.Constants -- A.4.6; Preelaborate
Depends on Ada.Strings.Maps, see that package's discussion.
Ada.Strings.Unbounded -- A.4.5; Preelaborate
Depends on Ada.Strings.Maps, see that package's discussion.
Ada.Strings.Wide_Bounded -- A.4.7; Preelaborate
Depends on Ada.Strings.Wide_Maps, see that package's discussion.
Ada.Strings.Wide_Fixed -- A.4.7; Preelaborate
Depends on Ada.Strings.Wide_Maps, see that package's discussion.
Ada.Strings.Wide_Maps -- A.4.7; Preelaborate
This package contains a named access type, and thus cannot be pure.
Ada.Strings.Wide_Maps.Wide_Constants -- A.4.7; Preelaborate
Depends on Ada.Strings.Wide_Maps, see that package's discussion.
Ada.Strings.Wide_Unbounded -- A.4.7; Preelaborate
Depends on Ada.Strings.Wide_Maps, see that package's discussion.
Ada.Synchronous_Task_Control -- D.10; not categorized
This package is really an interface to the tasking runtime, and any state needed is either in it or in Suspension_Object. There should be no need for any separate initialization. The routines it depends upon must be able to be called from a pure package (it is perfectly possible to declare or rendezvous with a task in a pure package). Thus, this package should be Preelaborated.
Ada.Tags -- 3.9; not categorized
Package Tags has state, so it cannot be pure. That state is generally either set up at link-time (before elaboration) or during the elaboration of tagged types (that is, during the elaboration of other units). In either case, no complex state need be initialized at elaboration time. Thus, this package can be Preelaborated.
GNAT's implementation includes a large number of routines beyond those in the standard definition. Nevertheless, their package could be preelaborated. Janus/Ada uses a 'built-in' implementation of this package, thus the categorization has no impact on the implementation.
Ada.Task_Attributes -- C.7.2; not categorized
This package depends on Ada.Task_Identification and has and access type, so it cannot be pure. The state is either local or in the task runtime; but setting it could require copying the Initial_Value object, which is not allowed for a preelaborated package.
Ada.Task_Identification -- C.7.1; not categorized
This package is really an interface to the tasking runtime. It has no state of its own. This package should not be pure, because we do not want to support the use of task_ids in multiple partitions. It couldn't be preelaborated in Ada 95, because of the default initialized constant Null_Task_Id. With appropriate use of pragma Preelaboratable_Initialization, this limitation can be eliminated. The package has no state of its own, and the routines it depends upon must be able to be called from a pure package (it is perfectly possible to declare or rendezvous with a task in a pure package). Thus, this package should be Preelaborated.
GNAT's implementation uses a lot of dependencies but no state; dunno if this change would be difficult to implement. Janus/Ada uses a 'built-in' implementation of this package, thus the categorization has no impact on the implementation.
Ada.Text_IO -- A.10.1; not categorized The standard files require state and
potentially system subprogram calls to initialize. Therefore, Ada.Text_IO cannot be preelaborated.
Ada.Text_IO.Complex_IO -- G.1.3; not categorized
Depends on Ada.Text_IO, see the discussion of that unit.
Ada.Text_IO.Editing -- F.3.3; not categorized
Depends on Ada.Text_IO, see the discussion of that unit.
Ada.Text_IO.Text_Streams -- A.12.2; not categorized
Depends on Ada.Text_IO, see the discussion of that unit.
Ada.Unchecked_Conversion -- 13.9; Pure Ada.Unchecked_Deallocation -- 13.11.2; Preelaborate
Doesn't need to be pure because it uses a named access type, which is not allowed in a Pure package.
Ada.Wide_Text_IO -- A.11; not categorized
This should be the same as Ada.Text_IO; see the discussion there.
Ada.Wide_Text_IO.Complex_IO -- G.1.3; not categorized
This should be the same as Ada.Wide_Text_IO; see the discussion there.
Ada.Wide_Text_IO.Editing -- F.3.4; not categorized
This should be the same as Ada.Wide_Text_IO; see the discussion there.
Ada.Wide_Text_IO.Text_Streams -- A.12.3; not categorized
This should be the same as Ada.Wide_Text_IO; see the discussion there.
Interfaces -- B.2; Pure Interfaces.C -- B.3; Pure Interfaces.C.Pointers -- B.3.2; Preelaborate
Can't be Pure because it contains an access type.
Interfaces.C.Strings -- B.3.1; Preelaborate
Can't be Pure because it contains an access type.
Interfaces.COBOL -- B.4; Preelaborate
This contains variables Ada_to_Cobol and Cobol_to_Ada in the specification. Thus, it cannot be Pure.
Interfaces.Fortran -- B.5; Pure System -- 13.7; Preelaborate
This can't be pure because we don't want to System.Address to be transmitted between partitions.
System.Address_To_Access_Conversions -- 13.7.2; Preelaborate
Depends on System.
System.Machine_Code -- 13.8; unspecified
This package's contents and thus categorization are implementation-defined.
System.RPC -- E.5; not categorized
It is expected that this package will need to set up the communications channel when it elaborates, thus it cannot be Preelaborable.
System.Storage_Elements -- 13.7.1; Preelaborate Depends on System. System.Storage_Pools -- 13.11; Preelaborate Depends on System.
!example
None needed for this proposal.
--!corrigendum
!ACATS test
ACATS test(s) should be constructed to check that the listed packages are preelaborable.
!appendix

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

Questions? Ask the ACAA Technical Agent