!standard A.10.5(37) 07-11-26 AI05-0038-1/03 !standard A.10.7(8/1) !standard A.10.7(10) !standard A.10.7(12) !standard A.10.8(10) !standard A.10.8(24) !class binding interpretation 07-01-12 !status ARG Approved 7-0-2 06-11-09 !status work item 07-01-12 !status received 06-11-27 !priority Low !difficulty Easy !qualifier Omission !subject Minor Errors in Ada.Text_IO. !summary (1) No call of New_Line is made if Set_Line(1) is called, and the current line number is greater than 1. (2) procedures Look_Ahead and Get_Immediate raise Status_Error if the file is not open. (3) procedure Get for a modular type raises Data_Error if the value is not in the subtype Num. !question (1) According to A.10.5(37), a call of Set_Line (1) would lead to a call of New_Line (0) if the current line number is greater than 1. But that would raise Constraint_Error (Spacing has subtype Positive_Count). What is the intent? (2) A.10.6(9) does not cover Look_Ahead or Get_Immediate. But these routines have no statement that an empty file raises Status_Error. Surely that should happen for these routines. (3) A.10.8(10) indicates that Get raises Data_Error only if the value is outside of the base range. So what happens if the value is outside of the subtype Num but inside the base range? The Note A.10.8(24) says that it raises Data_Error, but there is no justification for this statement. !recommendation (See Summary.) !wording (1) Change the last sentence of A.10.5(37) to: If the value specified by To is less than the current line number, has the effect of calling New_Page followed, if To is greater than 1, by a call to New_Line with a spacing equal to (To - 1). (2) Add Status_Error is propagated if the file is not open. to A.10.7(8/1), A.10.7(10), and A.10.7(12) before the sentence starting "Mode_Error is raised..." (3) Change A.10.8(10) to: The exception Data_Error is propagated if the sequence of characters read does not form a legal integer literal or if the value obtained is not of the subtype Num. Delete A.10.8(24). !discussion (1) This error even appears in Ada 83. Clearly, Set_Line(1) should just call New_Page if the value of the current line is greater than 1. (2) We could fix this two ways, either by adding the missing rule to A.10.7(8/1), A.10.7(10), and A.10.7(12), or by changing A.10.6(9). Note that A.10.6(9) also covers Mode_Error, and it was not changed to cover these routines, either: the rule was added to each of the routines. Thus, we conclude it was intended to specify the rule in the definition of these routines, rather than changing the blanket definition. (3) Get could raise Constraint_Error in this case, but there doesn't seem to be any value in it being different than Get for Integers. Moreover, such a value cannot be Put (as it would raise Constraint_Error), so there is little reason to be able to read it. Finally, Get from a string always raises Data_Error when the value is outside of the subtype; it is bizarre that the file version of Get is different. [Editor's note: I did a bit of research on this to figure out when/why it was changed. Interestingly, RM9X 3.0 has the wording that we're going to switch to verbatim. It was changed in RM9x 4.0 to the current wording without explanation. Thus the rule is clearly intentional, but what the author was thinking is lost to the mists of time.] The note A.10.8(24) gives bounds that match neither the original Standard wording nor the proposed replacement wording. It is not worth preserving. !corrigendum A.10.5(37) @drepl @xbullet @dby @xbullet !corrigendum A.10.7(8/1) @drepl @xindent @dby @xindent !corrigendum A.10.7(10) @drepl @xindent @dby @xindent !corrigendum A.10.7(12) @drepl @xindent @dby @xindent !corrigendum A.10.8(10) @drepl The exception Data_Error is propagated if the sequence of characters read does not form a legal integer literal or if the value obtained is not of the subtype Num (for Integer_IO) or is not in the base range of Num (for Modular_IO). @dby The exception Data_Error is propagated if the sequence of characters read does not form a legal integer literal or if the value obtained is not of the subtype Num. !corrigendum A.10.8(24) @ddel @s9<30 For Modular_IO, execution of Get propagates Data_Error if the sequence of characters read forms an integer literal outside the range 0..Num'Last.> !ACATS test All of these changes just confirm the expected behavior (which doesn't match the wording), so there isn't a significant need for testing them. !appendix !topic New_Line called with Spacing = 0 !reference Ada 2005 RM-A.10.5(37) !author Christoph Grein 2006-11-27 !discussion According to A.10.5(37), a call of Set_Line (1) would lead to a call of New_Line (0) if the current line number is greater than 1. (This is already in RM 83 14.3.4(36) - or am I blind?) **************************************************************** From: Tucker Taft Date: Monday, November 27, 2006 1:14 PM Good point. That wording has been around forever, and no-one bothered to analyze it closely. It is modeled on the "Set_Col" wording, which can legitimately talk about outputting "To-1" spaces even when To = 1. On the other hand, calling "New_Line(Spacing => To-1)" doesn't make sense for To = 1, because Spacing is of subtype Positive. I presume we all "know" what it means, i.e., do nothing, but it should probably be stated correctly. In general, the Ada Rapporteur Group has concluded that any time the manual says one thing is equivalent to something else (or in this case, "has the effect of calling..."), it is probably telling a lie (sometimes a small lie, sometimes a big one). **************************************************************** !topic No statement for Get_Immediate, Look_Ahead, when the file is not open. !reference Ada 2005 RM-A.10.7(8/1,10,12) !author Christoph Grein 2006-12-01 !discussion This is a very minor point, but contrary to all other file operations, the paragraphs about Get_Immediate and Look_Ahead do not state what should happen if the file is not open. RM-A.10.6(9) does not apply. **************************************************************** !topic Inconsistent handling of Get for modular types !reference RM A.10.8(10) !from Christoph Grein 07-03-02 !discussion Consider the following program fragment: type Test_Modular is mod 2**10; subtype Test_Range is Test_Modular range 0 .. +1000; -- Test_Range'Base 0 .. 1023 package Test_Modular_Text_IO is new Ada.Text_IO.Modular_IO (Test_Range); use Test_Modular_Text_IO; Unsigned: Test_Modular; Get (File, Unsigned); According to A.10.8(10), the value 1023 can be read into Unsigned without raising Data_Error (contrary to a signed integer). This is what Bob Duff told me when I asked about this behaviour: The RM seems inconsistent on this point. A.10.8(10) does indeed seem to say that the base range is what matters. However, this makes no sense, for several reasons: - The subtype of the parameter is Num, not Num'Base, so it is impossible to return 1023 in your example (unless we go completely outside normal Ada semantics -- and Text_IO is supposed to be implementable in normal Ada code). - The NOTE in para 24 contradicts A.10.8(10): For Modular_IO, execution of Get propagates Data_Error if the sequence of characters read forms an integer literal outside the range 0..Num'Last. - To me, it makes no sense to raise Constraint_Error for 1023 but Data_Error for 1025. - Modular_IO.Put cannot put the number 1023, so why should Get be able to read it? - I see no value to the programmer in using the base range. If you want the base range, instantiate with that subtype. (In fact, I'd say a good rule of thumb is to never use subranges of modular types, nor arrays indexed by modular types, except in special circumstances, such as interfacing with C code.) Therefore, we're going to guess that A.10.8(10) is simply a mistake, and the intent is that Data_Error be raised for numbers outside the range of Num. End of quote. ****************************************************************