CVS difference for ais/ai-00227.txt

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

--- ais/ai-00227.txt	2000/03/14 00:05:55	1.1
+++ ais/ai-00227.txt	2000/03/15 18:52:56	1.2
@@ -1,17 +1,18 @@
-!standard 13.13.1    (4)                             00-03-13  AI95-00227/01
+!standard 13.13.1    (4)                             00-03-15  AI95-00227/02
 !standard 13.13.1    (5)
 !standard 13.13.1    (8)
-!class confirmation 00-03-13
+!class binding interpretation 00-03-15
 !status work item 00-03-13
 !status received 00-02-09
-!priority Low
+!priority Medium
 !difficulty Easy
-!subject Behavior of Ada.Streams.Read when Last is not in the base type
+!subject Behavior of Ada.Streams.Read when at the end of stream
 
 !summary
 
-Ada.Streams.Read raises Constraint_Error if Item'First =
-Stream_Element_Offset'First and no elements are read.
+Ada.Streams.Read returns Item'First - 1 in Last when no elements are
+transferred. If Item'First = Stream_Element_Offset'First and no elements
+are transferred, Constraint_Error is raised.
 
 !question
 
@@ -24,8 +25,8 @@
       of Stream_Element;
 
    procedure Read (Stream : in out Root_Stream_Type;
-                            Item : out Stream_Element_Array;
-                            Last : out Stream_Element_Offset) is abstract;
+                   Item : out Stream_Element_Array;
+                   Last : out Stream_Element_Offset) is abstract;
 
 Consider the following case:
 
@@ -40,22 +41,66 @@
 If Strm is at end of stream, such that no elements are read, what is the
 value of Last? (Constraint_Error is raised).
 
-!response
+!recommendation
 
-13.13.1(8) says that Last is set to the index of the last element transfered.
-If no items are transfered, this means that the value of Last must be less than
-Item'First. If Item'First = Stream_Element_Offset'First, this value will be
-out of the range of the base type, and thus will raise Constraint_Error.
+(See summary.)
 
-The fact that this routine was designed to avoid raising an exception even
-when nothing was read is irrelevant.
+!wording
+
+(See corrigendum.)
 
+!discussion
 
-(*** Note: 13.13.1(8) doesn't say what Last ought to be when no elements are
-transfered ***)
+13.13.1(8) says:
 
+The Read operation transfers Item'Length stream elements from the
+specified stream to fill the array Item. The index of the last stream
+element transferred is returned in Last. Last is less than Item'Last only if
+the end of the stream is reached.
 
+In order to answer the question, we need to know what the value of Last is when
+no elements are transferred. However, 13.13.1(8) doesn't say. The second
+sentence says that Last is set to the index of the last element transferred,
+but it says nothing about the value if no elements are transferred.
 
+We answer the question by appealing by analogy to the similar routine,
+Ada.Text_IO.Get_Line. A.10.7(20) says "If no characters are read,
+returns in Last an index value that is one less than Item'First." This result
+is known by every Ada programmer, and it seems best to define Ada.Streams.Read
+the same way.
+
+Having determined the value of Last, we can now answer the question. Last will
+be equal to Item'First - 1. If Item'First = Stream_Element_Offset'First, this
+value will be out of the range of the base type, and thus will raise
+Constraint_Error.
+
+The fact that this routine was designed to avoid raising an exception even
+when nothing was read is irrelevant. Users of Ada.Streams.Read ought to avoid
+passing in Item arrays whose lower bound is Item'First.
+
+!corrigendum 13.13.01(08)
+
+@drepl
+The Read operation transfers Item'Length stream elements from the
+specified stream to fill the array Item. The index of the last stream
+element transferred is returned in Last. Last is less than Item'Last only if
+the end of the stream is reached.
+@dby
+The Read operation transfers Item'Length stream elements from the
+specified stream to fill the array Item. If elements are transferred, the index
+of the last stream element transferred is returned in Last. If no elements are
+transferred, Item'First - 1 is returned in Last. Last is less than Item'Last
+only if the end of the stream is reached.
+
+!corrigendum 13.13.01(10)
+
+@dinsa
+See A.12.1, ``The Package Streams.Stream_IO'' for an example of
+extending type Root_Stream_Type.
+@dinst
+If the end of stream has been reached, and Item'First is
+Stream_Element_Offset'First, Read will raise Constraint_Error.
+
 !ACATS test
 
 A C-test should be created (or better, added to an existing test) to test
@@ -343,15 +388,72 @@
 I should write the test.  --Ted
 
 *************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 13, 2000 1:31 PM
+
+I was writing up a confirmation AI on the stream elements question of last
+month (we have to consider an AI because I stupidly posted the message to
+Ada-Comment rather than here). Anyway, I had to fudge it a bit.
+
+13.13.1(8) says in part:
+
+The index of the last stream element transferred is returned in Last. Last
+is less than Item'Last only if the end of the stream is reached.
+
+This says nothing about the value of Last if no elements are transferred. I
+think everyone has *assumed* that it is Item'First - 1, but the wording
+above seems to leave it undefined (although it ought to be less than
+Item'Last).
+
+Is this defined somewhere else? If not, perhaps we ought to use the AI to
+repair this???
+
+*************************************************************
 
-Editors note (from Randy Brukardt)
+From: Tucker Taft
+Sent: Tuesday, March 14, 2000 12:54 PM
 
-13.13.1(8) doesn't really say what the value of Last is if no elements are
-transfered. Everyone "knows" it is Item'First-1, but the wording just says
-that it is the index of the "last element transfered".
+Why is this necessary to specify?  Isn't it Ok to leave it
+implementation-defined (i.e., the proper check is "Last < Item'First"
+rather than "Last = Item'First - 1")?
 
-Perhaps this AI needs to fix that??
+*************************************************************
 
+From: Randy Brukardt
+Sent: Tuesday, March 14, 2000 3:01 PM
+
+I suppose it isn't necessary to specify a particular value (although why we
+would want to bring all of the problems of super-null arrays into this case is
+beyond me), but it certainly is necessary to specify *something* about the
+value. The text does *not* specify that the value of Last must be less than
+Item'First; indeed it makes no requirements at all.
+
+Note that it says "Last is less than Item'Last only if the end of stream is
+reached." It does *not* say "If the end of stream is reached, Last is less than
+Item'Last.". So, returning Last = Item'Last + 1 would meet all of the
+requirements of the paragraph in the case where nothing was transferred.
+
+Indeed, if I wanted to split hairs, I could argue that the sentence "The index
+of the last stream element transferred is returned in Last." doesn't apply at
+all in this case, because nothing was transferred. That would make Last an
+uninitialized variable in that case: certainly a result we don't want.
+
 *************************************************************
 
+From: Tucker Taft
+Sent: Wednesday, March 15, 2000 9:26 AM
+
+Randy Brukardt wrote:
+> ...
+> Indeed, if I wanted to split hairs, I could argue that the sentence "The
+> index of the last stream element transferred is returned in Last." doesn't
+> apply at all in this case, because nothing was transferred. That would make
+> Last an uninitialized variable in that case: certainly a result we don't
+> want.
+
+I now agree with you that the wording needs fixing.  I would rewrite
+it in the spirit of the wording used for Get_Line -- A.10.7(20).
+
+*************************************************************
 

Questions? Ask the ACAA Technical Agent