CVS difference for ais/ai-00404.txt

Differences between 1.4 and version 1.5
Log of other versions for file ais/ai-00404.txt

--- ais/ai-00404.txt	2005/03/15 02:31:07	1.4
+++ ais/ai-00404.txt	2005/04/13 05:37:22	1.5
@@ -1,6 +1,8 @@
-!standard 3.10(6)                                      05-02-14  AI95-00404/03
+!standard 3.10(6)                                      05-03-14  AI95-00404/04
 !standard 3.9.2(11)
 !class amendment 05-01-28
+!status Amendment 200Y 05-03-14
+!status ARG Approved 6-0-2  05-02-14
 !status work item 05-01-28
 !status received 05-01-28
 !status received
@@ -11,9 +13,10 @@
 !summary
 
 Not null is implicit, but may be given explicitly, for controlling
-access parameters and results. When defined by a renaming or
-a generic instantiation, the controlling access parameters and
-results must be null excluding.
+access parameters. When defined by a renaming or
+a generic instantiation, the controlling access parameters
+must be null excluding. Note that controlling access results
+are not automatically null excluding.
 
 All is not permitted as a general access modifier for anonymous access
 types.
@@ -49,10 +52,10 @@
 Add after 3.9.2(11):
 
   If a dispatching operation is defined by a subprogram_renaming_declaration
-  or the instantiation of a generic subprogram, any access parameter or
-  access result of the renamed subprogram or the generic subprogram
-  that corresponds to a controlling access parameter or controlling access
-  result of the dispatching operation, shall be null excluding.
+  or the instantiation of a generic subprogram, any access parameter of the
+  renamed subprogram or the generic subprogram that corresponds to a
+  controlling access parameter of the dispatching operation, shall be
+  null excluding.
 
 AARM Note on incompatibility:
   This rule will require the addition of an explicit "not null" on
@@ -64,7 +67,7 @@
 The draft rationale says:
 
    For uniformity, Ada 2005 permits all three forms with anonymous access types.
-   And we can also add not null so we can write all the following in Ada 2005
+   And we can also add not null so we can write all the following in Ada 2005:
 
    procedure P1(X: access T)
    procedure P2(X: access constant T);
@@ -115,12 +118,12 @@
 not null everywhere. We considered disallowing an explicit not null
 where they are implicit, but it was anticipated that after a transition
 period, explicit not null would be used everywhere it applies, and disallowing
-its use for controlling access parameters or results would defeat this.
+its use for controlling access parameters would defeat this.
 
 For a dispatching operation defined by renaming or instantiation, we require
 that the renamed subprogram or generic subprogram be null excluding for each
 access parameter or access result that ends up controlling in the renaming or
-the instance.  For example:
+the instance. For example:
 
    generic
       type GT is private;
@@ -146,12 +149,45 @@
       procedure Inst2 is new Gen_Subp_2(T); -- legal
    end P;
 
+Note that we considered imposing a similar implicit null exclusion for
+controlling access results, but chose not to do that, because there is
+no Ada95 compatibility issue, and there is no automatic null check
+inherent in the use of a controlling access result. If a null check is
+necessary, it is because there is a dereference of the result. If there
+is no dereference of the result, a null return value is perfectly
+acceptable, and can be a useful indication of a particular status of the
+call.
+
 !example
 
 (See discussion.)
+
+!corrigendum 3.9.2(11)
+
+@dinsa
+The @fa<default_expression> for a controlling formal parameter of a dispatching
+operation shall be tag indeterminate. A controlling formal parameter that is an
+access parameter shall not have a @fa<default_expression>.
+@dinst
+If a dispatching operation is defined by a @fa<subprogram_renaming_declaration>
+or the instantiation of a generic subprogram, any access parameter of the
+renamed subprogram or the generic subprogram that corresponds to a
+controlling access parameter of the dispatching operation, shall be
+null excluding.
+
+!corrigendum 3.10(6)
+
+@drepl
+@xcode<@fa<access_definition ::= >@ft<@b<access>>@fa< subtype_mark>>
+@dby
+@xcode<@fa<null_exclusion ::= >@ft<@b<not null>>
+@fa<access_definition ::=
+   [null_exclusion] >@ft<@b<access>>@fa< [>@ft<@b<constant>>@fa<] subtype_mark
+ | [null_exclusion] >@ft<@b<access>>@fa< [>@ft<@b<protected>>@fa<] >@ft<@b<procedure>>@fa< parameter_profile
+ | [null_exclusion] >@ft<@b<access>>@fa< [>@ft<@b<protected>>@fa<] >@ft<@b<function>>@fa< parameter_and_result_profile>>
 
---!corrigendum
 
+
 !ACATS test
 
 Create B-Tests to check that the renames and instance rule is checked.
@@ -159,4 +195,111 @@
 
 !appendix
 
+From: Tucker Taft
+Sent: Friday, February 18, 2005  6:18 AM
+
+The other "morning after" issue that I remember has
+to do with access results.  Erhard made the point that
+by associating non-nullness with controlling access results,
+we will make it that much harder to use them as a replacement
+for named access types.  Although I argued against his
+point in the meeting, afterward I realized there really
+isn't much justification for requiring that controlling access
+results be non-null.
+
+There are several ways in which controlling access results
+are different from controlling access parameters:
+
+   1) We don't have any "legacy"/"compatibility" to worry
+      about here.  Access results didn't exist in Ada 95,
+      so we don't have to inherit their rules.  We can
+      easily say that with controlling access results, you
+      get what you ask for, either null-excluding or
+      null-allowing, whichever is more appropriate.
+
+   2) With controlling access parameters, there is a necessary
+      dereference on every dispatching call to find out which
+      body to execute, or in the case of multiple parameters,
+      to make sure they all agree on which body.  With controlling
+      access results, there is no such requirement, except when
+      the controlling access result is passed to a null-excluding
+      parameter or assigned to a null-excluding target, and then
+      the check is really associated with the target, not the
+      result.
+
+   3) Given "function Empty_Acc return access Set:" and
+      "X : access Set'Class;" I had leapt to the conclusion
+      that "X := Empty_Acc;" was dispatching on result.
+      But that's wrong.  We are doing an access value
+      assignment, and there is certainly no requirement that
+      X be non-null to begin with.  A dispatching on result
+      would only occur with:  "X.all := Empty_Acc.all;" in
+      which case we have the ".all" on Empty_Acc which clearly
+      inserts the appropriate null check, so again, there is
+      no need to associate it with Empty_Acc itself.
+
+   4) Unlike with normal results, with access results, "null"
+      is a well-defined value that could be returned from
+      a primitive function.  For example, consider the
+      C++ streaming approach, where the streaming "get"
+      returns the input stream:
+
+           function Get(S : access Stream; Val : access Integer)
+             return access Stream;
+           function Get(S : access Stream; Val : access Float)
+             return access Stream;
+
+      We could also have other operations that produce streams
+      or add characters into a stream for later "Get"s,
+      which would look more like constructors:
+
+           function Open(Name : String) return access Stream;
+           function Init_Contents(Contents : String)
+             return access Stream;
+           function Unget_String(S : access Stream; Put_Back : String)
+             return access Stream;  -- "Put_Back" inserted
+                                    -- back into stream for Get
+                                    -- to re-read
+
+      A "null" value could be used as an indication of an empty stream.
+
+      One could then write:
+
+           Str : access Stream := Open("My_File");
+           A, B : aliased Integer;
+           C : aliased Float;
+         begin
+           while Str /= null loop
+              Str := Str.Get(A'Access).Get(B'Access).Get(C'Access);
+              -- Do something with A, B, C
+           end loop;
+
+      Of course some people don't like using "null" as an indicator,
+      but it is pretty common (certainly when iterating over a
+      linked list, for example).  But in any case, it seems
+      a conceivable thing to do, and there seems no reason
+      why we need to disallow it or make it more difficult
+      than necessary.
+
+----------------------
+
+So for all the above reasons, and perhaps more, I would
+suggest we drop the connection between non-nullness and
+controlling access results, and adopt a "what you see
+is what you get" model for them.  I believe it might have
+been an overactive attempt to unify, otherwise known as "confuse,"
+controlling access parameters and controlling access
+results, which led us to believe they were necessarily
+non-null.  In other words, I think Erhard had the right
+instinct here...
+
 *************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February 22, 2005  4:11 AM
+
+I agree with your arguments: there doesn't seem to be any good reason to
+force access results to be null-excluding.
+
+*************************************************************
+

Questions? Ask the ACAA Technical Agent