CVS difference for ais/ai-00362.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00362.txt

--- ais/ai-00362.txt	2003/11/27 02:01:16	1.2
+++ ais/ai-00362.txt	2004/02/21 04:15:11	1.3
@@ -1,4 +1,4 @@
-!standard  03.09(06)                                   03-11-26  AI95-00362/01
+!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)
@@ -13,7 +13,7 @@
 !status received 03-10-04
 !priority Medium
 !difficulty Medium
-!subject Some predefined packages should be preelaborated
+!subject Some predefined packages should be recategorized
 
 !summary
 
@@ -22,23 +22,35 @@
 !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.
+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
 
-[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.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.
@@ -54,25 +66,27 @@
    package Ada.Exceptions is
       pragma Preelaborate(Exceptions);
       type Exception_Id is private;
-      pragma Preelaboratable_Initialization (Exception_Id);
+      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 Preelaboratable_Initialization (Exception_Occurrence);
+      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);
-
-Add after A.8.1(2):
-      pragma Preelaborate(Sequential_IO);
 
-Add after A.8.4(2):
-      pragma Preelaborate(Direct_IO);
+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
@@ -110,25 +124,36 @@
 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.]
+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
@@ -156,6 +181,11 @@
 
   [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
@@ -163,7 +193,8 @@
   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.
+  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
@@ -175,18 +206,24 @@
 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.
+  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
@@ -195,7 +232,10 @@
   (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 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
@@ -204,11 +244,13 @@
   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'
+  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
@@ -240,7 +282,7 @@
   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.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
@@ -258,44 +300,63 @@
   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.
+  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.
+  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
-  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.
+  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
-  Depends on Ada.Strings.Maps, see that package's discussion.
+  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
-  Depends on Ada.Strings.Maps, see that package's discussion.
+  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 type, and thus cannot be pure.
+  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
-  Depends on Ada.Strings.Maps, see that package's discussion.
+  Since Ada.Strings.Maps is not pure, this package can be as well.
 Ada.Strings.Unbounded -- A.4.5; Preelaborate
-  Depends on Ada.Strings.Maps, see that package's discussion.
+  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 type, and thus cannot be pure.
+  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
@@ -318,7 +379,7 @@
   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,
+  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.
@@ -333,13 +394,13 @@
   (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'
+  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 -- 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
@@ -361,25 +422,29 @@
 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.
+  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.
+  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.
+  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.
+  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.
-System.Storage_Pools -- 13.11; Preelaborate Depends on System.
+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
 
@@ -390,7 +455,7 @@
 !ACATS test
 
 ACATS test(s) should be constructed to check that the listed packages
-are preelaborable.
+are pure and/or preelaborable.
 
 !appendix
 

Questions? Ask the ACAA Technical Agent