CVS difference for ais/ai-00231.txt

Differences between 1.13 and version 1.14
Log of other versions for file ais/ai-00231.txt

--- ais/ai-00231.txt	2004/01/23 04:59:24	1.13
+++ ais/ai-00231.txt	2004/05/29 00:38:34	1.14
@@ -1,4 +1,4 @@
-!standard  3.10      (06)                        04-01-10  AI95-00231/08
+!standard  3.10      (06)                        04-05-24  AI95-00231/09
 !standard  3.2.3     (03)
 !standard  3.2.3     (05)
 !standard  3.7       (05)
@@ -43,15 +43,17 @@
 !proposal
 
 Change non-controlling access parameters and access discriminants to
-allow them to have null values.
+allow them to have null values. This represents a return to the original
+Ada 83 model where all access types include a null value.
 
-Introduce a "null exclusion," ("not null") and allow it on subtype indications,
+Allow the notion of a null-excluding access subtype, by introducing a
+a "null exclusion" ("not null"), and allow it on subtype indications,
 access type definitions, and access definitions. We don't call it a
 "constraint" because doing so creates various wording issues relating to
-"constrained" versus "unconstrained."
+"constrained" versus "unconstrained".
 
-Generalize access_definition to allow specification of access-to-constant, and
-a null exclusion.
+Generalize access_definition to allow specification of access-to-constant and
+a null exclusion for anonymous access types.
 
 !wording
 
@@ -69,11 +71,11 @@
 
 Modify the first sentence of 3.7(9):
 
-    The subtype of a discriminant may be defined by {an optional null_exclusion and} a
-    subtype_mark, in which case the subtype_mark shall denote a discrete or access
-    subtype, .... is of an anonymous [general access-to-variable]
-    {access} type [whose designated subtype is denoted by the subtype_mark
-    of the access_definition].
+    The subtype of a discriminant may be defined by {an optional null_exclusion
+    and} a subtype_mark, in which case the subtype_mark shall denote a discrete
+    or access subtype, .... is of an anonymous [general access-to-variable]
+    {access} type [whose designated subtype is denoted by the subtype_mark of
+    the access_definition].
 
 
 Modify 3.10(2) to:
@@ -92,7 +94,7 @@
 Modify 3.10(12) to:
 
     An access_definition defines an anonymous general access type; the subtype
-    mark denotes its @i<designated subtype>. If the word @b<constant> appears,
+    mark denotes its designated subtype. If the word constant appears,
     the type is an access-to-constant type; otherwise it is an
     access-to-variable type. If a null_exclusion is present, or the
     access_definition is for a controlling access parameter (see 3.9.2), the
@@ -102,29 +104,36 @@
     parameter (see 6.1). [NOTE: Drop this last sentence if AI-230 is approved.]
 
    AARM Note: Controlling access_definitions are null-excluding because it
-   it necessary to read the tag to dispatch, and @b<null> has no tag. We
-   would have preferred to require @b<not null> to be specified for such
+   is necessary to read the tag to dispatch, and null has no tag. We
+   would have preferred to require not null to be specified for such
    parameters, but that would have been too incompatible with Ada 95.
 
 Modify 3.10(13) as follows:
-   For each [(named)] access type, there is [a literal NULL which has] a null
+   For each [(named)] access type, there is [a literal null which has] a null
    access value designating no entity at all.  The null value of [a named] {an}
    access type is the ... in the case of [a named] {an} access-to-object type,
    an allocator, which returns ...
 
-Add the following sentence to the end of 3.10(14):
+Add the following sentence to the end of 3.10(14/1):
     The first subtype of a type defined by an access_type_definition excludes
     the null value if a null_exclusion is present; otherwise, the first subtype
     includes the null value.
 
+Add after 3.10(14/1):
+
+            Legality Rules
+
+    A null_exclusion is only allowed in a subtype_indication whose subtype_mark
+    denotes an access subtype that includes a null value.
+
 Modify 3.10(15) as follows:
 
     A composite_constraint is compatible with an unconstrained access subtype
     if it is compatible with the designated subtype. {A null_exclusion is
-    compatible with an access subtype if the subtype includes a null value.} An
+    compatible with any access subtype that includes a null value.} An
     access value satisfies a composite_constraint of an access subtype if it
     equals the null value of its type or if it designates an object whose value
-    satisfies the constraint. {An access value satisifes a null_exclusion
+    satisfies the constraint. {An access value satisfies a null_exclusion
     imposed on an access subtype if it does not equal the null value of its
     type.}
 
@@ -191,7 +200,7 @@
       -- X guaranteed to not be null
 
     procedure Pass_By_Ref(Y : not null access constant Rec);
-      -- Pass Y by reference, but don't allow it to be updated;
+      -- Pass Y.all by reference, but don't allow it to be updated;
       -- Guarantee Y is non-null.
 
     procedure Display(W : access Window; G : access constant Graph'Class);
@@ -213,19 +222,22 @@
 
 The rule disallowing "null" for access parameters and access discriminants has
 turned out to be confusing, and not what is wanted in all cases when
-interfacing with a foreign language. Therefore, we propose to define an
-explicit way to exclude nulls from an access subtype, and make "access T" and
-"access constant T" include nulls by default when not a controlling parameter,
-even though this does not preserve complete upward compatibility. Note that
-the only incompatibility is for cases where null was passed, and these would
-have been rejected at compile-time or have raised Constraint_Error. It was
-felt it was better to have this upward incompatibility than to have the default
-be null-excluding for "access T" but not null-excluding for "access constant
-T". Note that there is no upward incompatibility for controlling access
-parameters; they always have null-excluding subtypes. Any worrisome loss of
-efficiency due to allowing null for non-controlling access parameters, or
-access discriminants, can be reversed by using an explicit
-null_exclusion.
+interfacing with a foreign language. Therefore, we propose to revert to the
+Ada 83 model where all access types include a null value, and to define an
+explicit way to exclude nulls from an access subtype. "Access T" and
+"access constant T" will include nulls by default (when not a controlling
+parameter), even though this does not preserve complete upward compatibility.
+
+Note that the only incompatibility is for cases where null was passed, and
+these would have been rejected at compile-time or have raised Constraint_Error.
+It was felt it was better to have this upward incompatibility than to have the
+default be null-excluding for "access T" but not null-excluding for "access
+constant T". Note that there is no upward incompatibility for controlling
+access parameters; they always have null-excluding subtypes. Any worrisome loss
+of efficiency due to allowing null for non-controlling access parameters, or
+access discriminants, can be reversed by using an explicit null_exclusion. (It
+would be easy to create a tool that added needed null_exclusions to Ada 95
+programs.)
 
 The general ability to specify an access subtype that excludes null for both
 named and anonymous access types can provide useful documentation and higher
@@ -235,8 +247,7 @@
 What should be the default initialization of an object of a subtype that
 excludes null? It seems clear that the default is still null, and the
 initialization will raise Constraint_Error. Hence, objects of such a subtype
-will require explicit initialization. Perhaps a NOTE to this effect should be
-included in 3.10.
+will require explicit initialization in order to be useful.
 
 Note that the "all" in an access_definition is redundant, since
 anonymous access types are always considered "general" access
@@ -252,19 +263,73 @@
 dimension. It also significantly simplifies generic sharing if
 null exclusion is known statically.
 
-Note that if one has a generic whose formal includes null,
+Note that we do not allow a null exclusion to be applied to an
+already null-excluding subtype. This is analogous to the restriction
+against reconstraining non-scalar subtypes. Given that we require
+matching of null exclusion in generics, it will always be known
+statically whether a given subtype excludes null, so there seems
+no reason to allow "confirming" null exclusions. Just as likely it
+might represent a confusion on the part of the programmer, so disallowing
+it might help detect such confusion.
+
+We discussed situations where you might want a single generic
+to be usable with both null including and null excluding actual
+subtypes. However, if one has a generic whose formal includes null,
 and one wants to reuse it with an access subtype that excludes null,
 you can do the instantiation using a null-including subtype of
 the same access type and accomplish the same level of reuse.
-The major advantage of this approach is that the generic can
-still declare default-initialized local variables of the access type,
-without bumping into the null exclusion. The instantiatior only
-cares about null exclusion when values are returned, and these checks
-would still be performed. Forcing the generic itself to operate
-internally obeying null exclusion would make it that much harder to
-reuse the generic.
 
+A major advantage of requiring the actual to include null if the formal does is
+that the generic can still declare default-initialized local variables of the
+access type, without bumping into the null exclusion. The instantiatior only
+cares about null exclusion on values returned from the instance, and these
+checks would still be performed as part of assigning a returned value to a
+variable of a null-excluding subtype. Forcing the generic itself to operate
+internally obeying null exclusion would make it that much harder to reuse the
+generic. For example:
+
+    generic
+        with type Designated_Type is limited private;
+        with type Formal_Acc is access Designated_Type;
+    procedure Gen(Ptr : in out Formal_Acc);
+
+    procedure Gen(Ptr : in out Formal_Acc) is
+        Local : Formal_Acc;  -- defaults to null
+    begin
+        Local := new Designated_Type;
+        if Ptr /= null then
+            Ptr := Local;
+        end if;
+    end Gen;
+
+    type Acc_With_Null is access T;
+    subtype Acc_Non_Null is non null Acc_With_Null;
+
+    procedure Instance is new Gen(Acc_With_Null);
+      -- Instantiate with null-including subtype
+
+    Y : Acc_Non_Null := new T;
+
+  begin
+
+    Instance(Ptr => Y);
+
+Inside Gen, "Ptr" and other objects of type "Formal_Acc" (e.g. "Local") can
+take on null values.  However, on return from the call, if the actual
+associated with "Ptr" is of a null-excluding subtype, then the appropriate
+check for null will be performed. The instantiator doesn't care if somewhere
+inside "Gen" there are pointers that are temporarily null. (Note that this
+works because parameters of an access type use pass-by-copy. This approach
+would not work if access values were passed by reference.)
+
+Note that the complementary requirement is also important, namely that if the
+formal excludes null, then so should the actual. This allows the code inside
+the generic to assume that any object or component that is of the formal type
+is non-null, even if it is passed from outside the generic. Hence, we
+require matching both ways, namely the actual may exclude null if
+and only if the formal excludes null.
 
+
 [Note: In the !corrigendum wording below, we assume that AI-230 is also
 approved.]
 
@@ -378,9 +443,14 @@
 of a type defined by an @fa<access_definition> or an
 @fa<access_to_object_definition> is unconstrained if the designated subtype is
 an unconstrained array or discriminated subtype; otherwise it is constrained.
-The first subtype of a type defined by an access_type_definition excludes the
-null value if a @fa<null_exclusion> is present; otherwise, the first subtype
-includes the null value.
+The first subtype of a type defined by an @fa<access_type_definition> excludes
+the null value if a @fa<null_exclusion> is present; otherwise, the first
+subtype includes the null value.
+
+@i<@s8<Legality Rules>>
+
+A @fa<null_exclusion> is only allowed in a @fa<subtype_indication> whose
+@fa<subtype_mark> denotes an access subtype that includes a null value.
 
 !corrigendum 3.10(15)
 
@@ -393,7 +463,7 @@
 @dby
 A @fa<composite_constraint> is @i<compatible> with an unconstrained access
 subtype if it is compatible with the designated subtype. A @fa<null_exclusion>
-is compatible with an access subtype if the subtype includes a null value. An
+is compatible with any access subtype that includes a null value. An
 access value @i<satisfies> a @fa<composite_constraint> of an access subtype if
 it equals the null value of its type or if it designates an object whose value
 satisfies the constraint. An access value satisifes a @fa<null_exclusion>
@@ -458,7 +528,7 @@
 @fa<parameter_specification>.
 @dby
 The nominal subtype of a formal parameter is the subtype determined
-by the optional @fa<null_exclusion> and the subtype_mark, or
+by the optional @fa<null_exclusion> and the @fa<subtype_mark>, or
 defined by the @fa<access_definition>, in the @fa<parameter_specification>.
 
 !corrigendum 6.1(24)

Questions? Ask the ACAA Technical Agent