Version 1.3 of ais/ai-00362.txt

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

!standard 03.09(06)          04-02-20 AI95-00362/02
!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 recategorized
!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. AI-366 loosens the restrictions on pure packages. All Ada 95 packages should be checked to insure that they are categorized correctly.
Preelaborated units automatically eliminate some sources of potential error (including some checks that otherwise would have to be done at runtime). Thus, it is to the advantage of Ada programmers to use them whereever possible. But the categorization of predefined packages makes that impossible in many cases where it otherwise would be possible:
Specific problems that have been identified include:
* Ravenscar and other restricted environments map naturally to preelaborated units, but most real-time packages can't be used in preelaborated units.
* raising and handling exceptions with information is needed in preelaborated units; but Ada.Exceptions is not usable in such units;
* All forms of I/O are prohibited in preelaborated units (no predefined I/O package is preelaborated), making it difficult to use preelaborated units in environments where logging/field debugging are necessary (such as unattended servers).
!proposal
Ada.Asynchronous_Task_Control is declared preelaborated. Ada.Characters.Handlers is declared pure. Ada.Dynamic_Priorities is declared preelaborated. Ada.Exceptions is declared preelaborated. Ada.Strings.Maps is declared pure. Ada.Strings.Maps.Constants is declared pure. 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 Preelaborable_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 Preelaborable_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);
Change A.4.3(3) to
package Ada.Strings.Maps is pragma Pure(Maps);
Change A.4.6(3) to
package Ada.Strings.Maps.Constants is pragma Pure(Constants);
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.
We also asked implementers for comments on the difficulty of implementing the first version of this proposal. Two implementers responded. DDCI reported that they made the changes proposed and that no problems surfaced other than with Ada.Characters.Mapping (which is solved by more recent versions of the proposal). They would not want to see more extensive changes.
IBM Rational reported that making the I/O packages preelaborated would require some rework. Moreover, Sequential_IO and Direct_IO included elaboration-time size determinations.
They noted that it would always be possible to rewrite the packages to an initialize-state-on-use strategy. (That is always a possible implementation when a package depends on complex state initialized at elaboration time.) They were concerned that a simple version of this (using a simple Boolean flag) would be fragile in the face of tasking. (Two tasks could trigger execution of the initialization at the same time). To fix that, an protected object (and its overhead) would be required. In addition, such a technique could be needed in a host of support units. Thus, restructuring of large parts of the runtime could be needed.
Because of these points (and the fact that other implementers expressed agreement with them), we did not propose to make any unit with significant initial state preelaborated.
[Open Issue: It has been suggested that providing a simple logging I/O package for use in preelaborated units would be a better alternative than trying to make any of the existing package preelaborated. Such a package would include only simple Open/Create/Delete/Close and Character and String I/O facilities (similar to those in Text_IO) in a preelaborated package. Should this idea be persued?]
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.]
Oddly, AI-161 declares Ada.Calendar.Time as a type that has preelaborable initialization, even though it is in a non preelaborated package. The text of the AI suggests that this is a mistake (it claims that these types are declared in preelaborated packages).
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. (And we're also proposing to change Ada.Strings.Maps.) 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.
However, most Ada implementations depend on a central IO package to implement all of the I/O. This package implements various operations that require state, such as file cleanup (to deal with files left open by the program), OS identification and the like. At least one implementer noted that extensive rewriting of the package would be needed to make it preelaborated. They also determined the size of file records at elaboration time.
The two implementations that we studied do not have problems. 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.
Still, given that a change here could cause extensive work, we are not recommending a change in categorization for Direct_IO.
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 (which do not meet any of the exceptions in AI-366). Moreover, many of its operations are not conceptually pure (they have significant side-effects).
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; we can't tell 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
The operations defined by this package are not conceptually pure, so this package should not be pure.
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; Pure 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. However, this package has the same issues as Direct_IO; see the discussion of that package.
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.
For the same reasons as Direct_IO, this package's categorization is not changed.
Ada.Storage_IO -- A.9; Preelaborate
This probably could be made pure, but there doesn't seem to be any need.
Ada.Streams -- 13.13.1; Pure Ada.Streams.Stream_IO -- A.12.1; not categorized
Any state that the operations need should be contained in the File_Type object; separate state is not needed. However, this package has the same issues as Direct_IO; see the discussion of that package.
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.
For the same reasons as Direct_IO, this package's categorization is not changed.
Ada.Strings -- A.4.1; Pure Ada.Strings.Bounded -- A.4.4; Preelaborate
This package contains no state, no dependence on non-pure units, no other items that prevent the package from being pure, and does not declare any types that would be a problem for Annex E, so it could be declared pure. But it's large and complex, and many of the operations are not conceptually pure (they do in-place updates), so no change is recommended.
Ada.Strings.Fixed -- A.4.3; Preelaborate
This package contains no state, no dependence on non-pure units, no other items that prevent the package from being pure, and does not declare any types that would be a problem for Annex E, so it could be declared pure. But it's large and complex, and many of the operations are not conceptually pure (they do in-place updates), so no change is recommended.
Ada.Strings.Maps -- A.4.2; Preelaborate
This package contains a named access-to-subprogram type. AI-366 makes it possible for such packages to be pure. This package contains no state, no dependence on non-pure units, no other items that prevent the package from being pure, and does not declare any types that would be a problem for Annex E. This package should be declared pure.
Ada.Strings.Maps.Constants -- A.4.6; Preelaborate
Since Ada.Strings.Maps is not pure, this package can be as well.
Ada.Strings.Unbounded -- A.4.5; Preelaborate
Any implementation will have to depend on Ada.Finalization.
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-to-subprogram type. AI-366 makes it possible for such packages to be pure. However, implementations of this package may use access types. Thus, we are not recommending any change here.
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 an 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; we cannot tell 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 that doesn't meet the exceptions of AI-161.
Interfaces.C.Strings -- B.3.1; Preelaborate
Can't be pure because it contains an access type that doesn't meet the exceptions of AI-161.
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; see the description of that package.
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; see the description of that package.
System.Storage_Pools -- 13.11; Preelaborate
Depends on System; see the description of that package.
!example
None needed for this proposal.
--!corrigendum
!ACATS test
ACATS test(s) should be constructed to check that the listed packages are pure and/or preelaborable.
!appendix

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

Questions? Ask the ACAA Technical Agent