!standard 4.1.3(17/2) 16-04-25 AI12-0178-1/04 !standard 4.3.2(13) !standard 4.3.3(45/2) !standard 4.5.2(37) !standard 8.3.1(12/2) !standard 9.7.3(6) !standard 9.11(7.1/2) !standard 10.1.2(29/2) !standard 11.2(12) !standard 11.4.3(2/2) !standard 11.4.3(5) !standard 11.4.3(6/2) !standard 11.4.3(10) !standard 12.1(22) !standard 12.3(24) !standard 12.7(19/2) !standard 12.7(21/2) !standard 13.5.1(27) !standard 13.11(41/3) !standard A.18.32(9/3) !standard B.4(124) !standard B.5(30/3) !standard C.3.2(28/3) !class presentation 15-10-09 !status Amendment 1-2012 16-02-29 !status WG9 Approved 16-06-13 !status ARG Approved 7-0-1 15-10-16 !status work item 15-10-09 !status received 15-09-07 !priority Low !difficulty Easy !qualifier Error !subject Glitches in examples !summary Correct a number of errors in examples in the Ada Standard. !question The examples in the Standard are intended to be compilable (if previous examples are included), and not all of them are. Should these be fixed? (Yes.) !recommendation (See Summary.) !wording Modify 4.1.3(17/2): (just the modified part shown) Pool(K).Write -- an entry of the task Pool(K) (see {9.1}[9.4]) Modify 4.3.2(13): (Expression with Left => {new Literal'(Value => }1.2{)},{ }Right => {new Literal'(Value => }3.4{)}) Addition'(Binop with null record) -- presuming Binop is of type Binary_Operation Modify 4.3.3(45/2): Buffer'(Size => 50, Pos => 1, Value => [String']('x', others => <>)) -- see 3.7 [Note: We have to remove the qualification, as qualifying by an unconstrained string type does not provide an "applicable index constraint" (4.3.3(13) does not apply) and thus the "others" is illegal. We wanted to use the applicable index constraint provided by the enclosing record (that is, to use 4.3.3(13)), so we don't want a qualification of any kind.] Replace 4.5.2(37) by: S : String := "A"; "" < S and S < "Aa" -- True S < "Bb" and S < "A " -- True [Note: We use a variable here to be as realistic as possible; qualifications would be a forward reference and obscure the point (ordering) of the example anyway. We know it's about ordering as John thinks he proposed adding this example of ordering to the RM in roughly 1980.] Modify 8.3.1(12/2): overriding procedure Remove_First(Q : in out Security_Queue; Person : [in]{out} Person_Name); Modify 9.7.3(6): (just the modified part shown) procedure Spin(R : in {out} Resource) is {-- see 9.4} [Note: It's necessary to have a variable to call an entry of a protected object, by 9.5(7.1/3). Resource is declared in the example of 9.4.] Insert before 9.11(8/2): type Person_Name_Array is array (Positive range <>) of Person_Name; -- see 3.10.1 [Note: This was identified in April 2011 (see !discussion of AI05-0248-1), but for some reason wasn't addressed. We do it now.] Modify 10.1.2(29/2): (just the modified part shown) type Department is [private]{...}; Modify 11.2(12): (just the modified part shown) {Ada.Exceptions.}Exception_Message Modify 11.4.3(2/2): package File_System is {type Data_type is ...; }type File_Handle is limited private; Modify 11.4.3(5): ... {private ...} end File_System; { AARM Reason: The first ... provides a place for Close to be declared, and the second ... provides a place for File_Handle to be completed.} Modify 11.4.3(6/2): (just the modified part shown) package body File_System is {...} [Editor's note: This will have to split this paragraph into 2 after ..., in order to be consistent with paragraphs 5 and 8.] { AARM Reason: This ... provides a place for File_Exists and the body of Close to be declared.} Modify 11.4.3(10): with Ada.Text_IO; with Ada.Exceptions; with File_System; use File_System; use Ada; procedure Main is { Verbosity_Desired : Boolean := ...; }begin [rest omitted] Modify 12.1(22): generic type Item {(<>)} is private; with function "*"(U, V : Item) return Item is <>; function Squaring(X : Item) return Item; Modify 12.3(24): function Square{1} is new Squaring(Item => Matrix, "*" => Matrix_Product); function Square{2} is new Squaring(Matrix, Matrix_Product); -- same as previous Modify 12.7(19/2): {subtype Key_String is String(1..5);} type String_Id is ... Modify 12.7(21/2): package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => {Key_}String, Element_Type => String_Id); Modify 13.5.1(27): type Byte_Mask is array (0..7) of Boolean{ with Component_Size => 1}; type State_Mask is array (State) of Boolean{ with Component_Size => 1}; type Mode_Mask is array (Mode) of Boolean{ with Component_Size => 1}; [Note: We're insisting on a particular component size, so we have to declare that.] Modify 13.11(41/3): Our_Pool : Mark_Release_Pool_Type (Pool_Size => 2000); My_Mark : [MR_Pool.]Subpool_Handle; -- {As declared in}[See] 13.11.6 Modify A.18.32(9/3): (just the modified part shown) use [Adjacency_Lists, ]Node_Maps, Paths, Graphs; [Note: This use is redundant with the one in A.18.32(4/3).] Modify B.4(124): (just the modified part shown) Ada_Record.Name := {COBOL.}To_Ada(COBOL_Record.Name); Ada_Record.SSN := {COBOL.}To_Ada(COBOL_Record.SSN); Modify B.5(30/3): (just the modified part shown) type Fortran_Matrix is array ({Fortran_}Integer range <>, {Fortran_}Integer range <>) of Double_Precision with Convention => Fortran; -- stored in Fortran's -- column-major order Modify C.3.2(28/3): (just the modified part shown) Device_Priority : constant array ({Ada.Interrupts.Interrupt_Id range }1..5) of{ }System.Interrupt_Priority := ( ... ); !discussion For the example in 13.11, the original comment was: This seems to have randomly selected just one of the places (Subpool_Handle) that use entities from "MR_Pool" to have an "MR_Pool." prefix. This was an incorrect intepretation of this example. The type Mark_Release_Pool_Type and its operations are declared here. The "..." at paragraph 40 includes the declarations of the Mark and Release operations -- that's what 13.11(38/3) says (or at least meant). We're not using "MR_Pool" here (that would be an unacceptable forward reference), but rather a set of declarations like it. The prefix in 13.11(41/3) shouldn't have been there and is now deleted. If we really wanted this to use "MR_Pool", we'd have to move the entire example to 13.11.6, which seems to defeat the purpose. --------- It was noted that the examples in 3.9.4, 4.1.5, 4.1.6, 8.3.1, and 9.11 all need to be in a package specification to be dispatching. As none of these examples is complete, and most them would need a forward reference in the RM to use a package (packages are introduced in Clause 7), we do not make any change to these examples. --------- Examples that could be better that we're not going to fix now: 3.6 A definition of type Error_Code would help. 3.8 A definition of type Month_Name would help. This was also pointed out in the !appendix of AI05-0248-1. 4.6 I think the last examples could do with a bit of context, e.g.: SS1 : Sequence := Sequence(Ledger); -- bounds are those of Ledger SS2 : Sequence := Sequence(Ledger(31 .. 42)); -- bounds are 31 and 42 DD : Dozen := Dozen(Ledger(31 .. 42)); -- bounds are those of Dozen 6.4 Pedantically the examples of function calls are function calls, but it would be more useful to have LHS := before and ; after. If we are going to be pedantic, then the examples of procedure calls are actually procedure call statements. !corrigendum 4.1.3(17/2) @dprepl @xcode>> @dby @xcode>> !corrigendum 4.3.2(13) @drepl @xcode<(Expression @b Left =@> 1.2, Right =@> 3.4) Addition'(Binop @b) --@ft<@i< presuming Binop is of type Binary_Operation>>> @dby @xcode<(Expression @b Left =@> @b Literal'(Value =@> 1.2), Right =@> @b Literal'(Value =@> 3.4)) Addition'(Binop @b) --@ft<@i< presuming Binop is of type Binary_Operation>>> !corrigendum 4.3.3(45/2) @drepl @xcode 50, Pos =@> 1, Value =@> String'('x', @b =@> <@>)) --@ft<@i< see 3.7>>> @dby @xcode 50, Pos =@> 1, Value =@> ('x', @b =@> <@>)) --@ft<@i< see 3.7>>> !corrigendum 4.5.2(37) @drepl @xcode<"" < "A" @b "A" < "Aa" --@ft<@i< True>> "Aa" < "B" @b "A" < "A " --@ft<@i< True>>> @dby @xcode S < "Aa" --@ft<@i< True>> S < "Bb" @b S < "A " --@ft<@i< True>>> !corrigendum 8.3.1(12/2) @drepl @xcode<@b @b Remove_First(Q : @b Security_Queue; Person : @b Person_Name);> @dby @xcode<@b @b Remove_First(Q : @b Security_Queue; Person : @b Person_Name);> !corrigendum 9.7.3(6) @dprepl @xcode<@b Spin(R : @b Resource) @b> @dby @xcode<@b Spin(R : @b Resource) @b --@ft<@i< see 9.4>>> !corrigendum 9.11(7.1/2) @dinsa The Buffer is defined as an extension of the Synchronized_Queue interface (see 3.9.4), and as such promises to implement the abstraction defined by that interface. By doing so, the Buffer can be passed to the Transfer class-wide operation defined for objects of a type covered by Queue'Class. @dinst @xcode<@b Person_Name_Array @b (Positive @b <@>) @b Person_Name; --@ft<@i< see 3.10.1>>> !corrigendum 10.1.2(29/2) @drepl @xcode<@b Office.Employees; @b Office.Departments @b @b Department @b;> @dby @xcode<@b Office.Employees; @b Office.Departments @b @b Department @b ...;> !corrigendum 11.2(12) @drepl @xcode<@b Open(File, In_File, "input.txt"); --@ft<@i< see A.8.2>> @b @b E : Name_Error =@> Put("Cannot open input file : "); Put_Line(Exception_Message(E)); --@ft<@i< see 11.4.1>> @b; @b;> @dby @xcode<@b Open(File, In_File, "input.txt"); --@ft<@i< see A.8.2>> @b @b E : Name_Error =@> Put("Cannot open input file : "); Put_Line(Ada.Exceptions.Exception_Message(E)); --@ft<@i< see 11.4.1>> @b; @b;> !corrigendum 11.4.3(2/2) @drepl @xcode<@b File_System @b @b File_Handle @b;> @dby @xcode<@b File_System @b @b Data_Type @b ...; @b File_Handle @b;> !corrigendum 11.4.3(5) @drepl @xcode< ... @b File_System;> @dby @xcode< ... @b ... @b File_System;> @xcode<@b File_System @b ...> !corrigendum 11.4.3(6/2) @drepl @xcode<@b File_System @b @b Open(F : @b File_Handle; Name : String) @b @b @b File_Exists(Name) @b ... @b @b File_Not_Found @b "File not found: " & Name & "."; @b; @b Open;> @dby @xcode< @b Open(F : @b File_Handle; Name : String) @b @b @b File_Exists(Name) @b ... @b @b File_Not_Found @b "File not found: " & Name & "."; @b; @b Open;> !corrigendum 11.4.3(10) @dprepl @xcode<@b Ada.Text_IO; @b Ada.Exceptions; @b File_System; @b File_System; @b Ada; @b Main @b @b> @dby @xcode<@b Ada.Text_IO; @b Ada.Exceptions; @b File_System; @b File_System; @b Ada; @b Main @b Verbosity_Desired : Boolean := ...; @b> !corrigendum 12.1(22) @drepl @xcode<@b @b Item @b; @b "*"(U, V : Item) @b Item @b <@>; @b Squaring(X : Item) @b Item;> @dby @xcode<@b @b Item (<@>) @b; @b "*"(U, V : Item) @b Item @b <@>; @b Squaring(X : Item) @b Item;> !corrigendum 12.3(24) @drepl @xcode<@b Swap @b Exchange(Elem =@> Integer); @b Swap @b Exchange(Character); --@ft<@i< Swap is overloaded >> @b Square @b Squaring(Integer); --@ft<@i< "*" of Integer used by default>> @b Square @b Squaring(Item =@> Matrix, "*" =@> Matrix_Product); @b Square @b Squaring(Matrix, Matrix_Product); --@ft<@i< same as previous>>> @dby @xcode<@b Swap @b Exchange(Elem =@> Integer); @b Swap @b Exchange(Character); --@ft<@i< Swap is overloaded >> @b Square @b Squaring(Integer); --@ft<@i< "*" of Integer used by default>> @b Square1 @b Squaring(Item =@> Matrix, "*" =@> Matrix_Product); @b Square2 @b Squaring(Matrix, Matrix_Product); --@ft<@i< same as previous>>> !corrigendum 12.7(19/2) @drepl @xcode< @b String_Id @b ...> @dby @xcode< @b Key_String @b String(1..5); @b String_Id @b ...> !corrigendum 12.7(21/2) @drepl @xcode< @b String_Table @b Ada.Containers.Ordered_Maps (Key_Type =@> String, Element_Type =@> String_Id);> @dby @xcode< @b String_Table @b Ada.Containers.Ordered_Maps (Key_Type =@> Key_String, Element_Type =@> String_Id);> !corrigendum 13.5.1(27) @drepl @xcode<@b Byte_Mask @b (0..7) @b Boolean; @b State_Mask @b (State) @b Boolean; @b Mode_Mask @b (Mode) @b Boolean;> @dby @xcode<@b Byte_Mask @b (0..7) @b Boolean @b Component_Size =@> 1; @b State_Mask @b (State) @b Boolean @b Component_Size =@> 1; @b Mode_Mask @b (Mode) @b Boolean @b Component_Size =@> 1;> !corrigendum 13.11(41/3) @drepl @xcode 2000); My_Mark : MR_Pool.Subpool_Handle; -- @ft<@i>> @dby @xcode 2000); My_Mark : Subpool_Handle; -- @ft<@i>> !comment AI12-0254-1 changes the following from A.18.32 to A.18.33. !corrigendum A.18.33(9/3) @drepl @xcode<@b Shortest_Paths @b @b Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) @b Paths.List @b @b Adjacency_Lists, Node_Maps, Paths, Graphs; Reached : @b (Node) @b Boolean := (@b =@> False); -- @ft<@i>> @dby @xcode<@b Shortest_Paths @b @b Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) @b Paths.List @b @b Node_Maps, Paths, Graphs; Reached : @b (Node) @b Boolean := (@b =@> False); -- @ft<@i>> !corrigendum B.4(124) @drepl @xcode< Ada_Record.Name := To_Ada(COBOL_Record.Name); Ada_Record.SSN := To_Ada(COBOL_Record.SSN); Ada_Record.Salary := To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First); Ada_Record.Adjust := To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate); ... --@ft<@i< Process Ada_Record>> @b; @b @b End_Error =@> ... @b Test_External_Formats;> @dby @xcode< Ada_Record.Name := COBOL.To_Ada(COBOL_Record.Name); Ada_Record.SSN := COBOL.To_Ada(COBOL_Record.SSN); Ada_Record.Salary := To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First); Ada_Record.Adjust := To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate); ... --@ft<@i< Process Ada_Record>> @b; @b @b End_Error =@> ... @b Test_External_Formats;> !corrigendum B.5(30/3) @drepl @xcode< @b Fortran_Matrix @b (Integer @b <@>, Integer @b <@>) @b Double_Precision @b Convention =@> Fortran; --@ft<@i< stored in Fortran's>> --@ft<@i< column-major order>> @b Invert (Rank : @b Fortran_Integer; X : @b Fortran_Matrix) @b Import =@> True, Convention =@> Fortran; --@ft<@i< a Fortran subroutine>>> @dby @xcode< @b Fortran_Matrix @b (Fortran_Integer @b <@>, Fortran_Integer @b <@>) @b Double_Precision @b Convention =@> Fortran; --@ft<@i< stored in Fortran's>> --@ft<@i< column-major order>> @b Invert (Rank : @b Fortran_Integer; X : @b Fortran_Matrix) @b Import =@> True, Convention =@> Fortran; --@ft<@i< a Fortran subroutine>>> !corrigendum C.3.2(28/3) @dprepl @xcode @b (1..5) of System.Interrupt_Priority := ( ... );> @dby @xcode @b (Ada.Interrupts.Interrupt_Id @b 1..5) @b System.Interrupt_Priority := ( ... );> !ASIS No ASIS effect. !ACATS test !appendix From: Jeff Cousins Sent: Monday, September 7, 2015 5:26 PM I've finished going through all the Ada RM examples, and here are the ones that I think need changing and those to think about. Examples that are wrong and should be fixed 4.1.3 The reference to 9.4 for Pool(K) should be to 9.1. 4.5.2 The string comparisons need qualifying with the type of string to avoid ambiguity. Example "" < "A" and "A" < "Aa" -- True "Aa" < "B" and "A" < "A " -- True should be String'("") < "A" and String'("A") < "Aa"; -- True String'("Aa") < "B" and String'("A") < "A "; -- True 12.7 String_Table is an Ordered_Map, not an Indefinite_Ordered_Map, so the Key_Type cannot be a String. package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => String, Element_Type => String_Id); could be subtype String_5 is String (1 .. 5); package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => String_5, Element_Type => String_Id); 13.11 This seems to have randomly selected just one of the places (Subpool_Handle) that use entities from MR_Pool to have an MR_Pool. prefix. Either there needs to be a "use MR_Pool;", or Mark_Release_Pool_Type, Mark and Release also need an MR_Pool. prefix. Our_Pool : Mark_Release_Pool_Type (Pool_Size => 2000); should be Our_Pool : MR_Pool.Mark_Release_Pool_Type (Pool_Size => 2000); My_Mark := Mark(Our_Pool); ... -- Allocate objects using "new (My_Mark) Designated(...)". Release(My_Mark); -- Finalize objects and reclaim storage. should be My_Mark := MR_Pool.Mark(Our_Pool); ... -- Allocate objects using "new (My_Mark) Designated(...)". MR_Pool.Release(My_Mark); -- Finalize objects and reclaim storage. B.4 The two "To_Ada"s need a COBOL. prefix (or there needs to be a "use COBOL;", but presumably the prefix is intended otherwise why bother with the renames). Ada_Record.Name := To_Ada(COBOL_Record.Name); Ada_Record.SSN := To_Ada(COBOL_Record.SSN); should be Ada_Record.Name := COBOL.To_Ada(COBOL_Record.Name); Ada_Record.SSN := COBOL.To_Ada(COBOL_Record.SSN); B.5 Type Fortran_Matrix has indexes of type Integer, but My_Matrix is declared with a bound of type Fortran_Integer. Either type Fortran_Matrix is array (Integer range <>, Integer range <>) of Double_Precision with Convention => Fortran; -- stored in Fortran's -- column-major order should be type Fortran_Matrix is array (Fortran_Integer range <>, Fortran_Integer range <>) of Double_Precision with Convention => Fortran; -- stored in Fortran's -- column-major order or My_Matrix : Fortran_Matrix (1 .. Rank, 1 .. Rank); should be My_Matrix : Fortran_Matrix (1 .. Integer (Rank), 1 .. Integer (Rank)); C.3.2 The index type of device priority is a discrete range, implying type Integer, so you can't index it with something of type Ada.Interrupts.Interrupt_Id. Either Device_Priority : constant array (1..5) of System.Interrupt_Priority := ( others => ... ); should be Device_Priority : constant array (Ada.Interrupts.Interrupt_Id range 1..5) of System.Interrupt_Priority := ( others => ... ); or with Interrupt_Priority => Device_Priority(Int_Id) is should be with Interrupt_Priority => Device_Priority(Integer(Int_Id)) is The former seems preferable to me. Examples where either the example or GNAT is wrong 4.3.3 For the final, Buffer, example, GNAT gives ""others" choice not allowed here", but not if not qualified with String'. If GNAT is correct, then example Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- see 3.7 should be Buffer'(Size => 50, Pos => 1, Value => ('x', others => <>)) -- see 3.7 GNAT is a bit prone to reporting strange errors if qualification is given where it is not required. 9.7.3 If Resource is the protected type in 9.4 rather than a task type (though it's not said to be), then the mode needs to be in out (and it would be useful to add a comment referring to 9.4). 13.5.1 According to GNAT (and Robert was very vocal on this subject) Byte_Mask, State_Mask and Mode_Mask need an aspect Pack. type Byte_Mask is array (0..7) of Boolean; type State_Mask is array (State) of Boolean; type Mode_Mask is array (Mode) of Boolean; should be type Byte_Mask is array (0..7) of Boolean with Pack; type State_Mask is array (State) of Boolean with Pack; type Mode_Mask is array (Mode) of Boolean with Pack; Examples that could be better 3.6 A definition of type Error_Code would help. 3.9.4 (and 8.3.1 and 9.1) The interfaces and their operations need to be in a package spec for the operations to be dispatching (and the packages "use"d for the subsequent code). Remove_First's parameter Person should be mode out, not in, to be mode conformant with 3.9.4. 4.1.5 & 4.1.6 The declarations need to be in a package spec for the subprograms to be dispatching. 4.3.2 (Expression with Left => 1.2, Right => 3.4); Assuming this is being assigned to something of type Binary_Operation (mentioned 2 lines later), then this fails since Left and Right are of type Expr_Ptr. We need something like: Literal_A : aliased Literal := Literal'(Value => 1.2); Literal_B : aliased Literal := Literal'(Value => 3.4); Binop : Binary_Operation := (Expression with Left => Literal_A'Access, Right => Literal_B'Access); 4.6 I think the last examples could do with a bit of context, e.g.: SS1 : Sequence := Sequence(Ledger); -- bounds are those of Ledger SS2 : Sequence := Sequence(Ledger(31 .. 42)); -- bounds are 31 and 42 DD : Dozen := Dozen(Ledger(31 .. 42)); -- bounds are those of Dozen 6.4 Pedantically the examples of function calls are function calls, but it would be more useful to have LHS := before and ; after. If we are going to be pedantic, then the examples of procedure calls are actually procedure call statements. 9.11 The declaration of protected Buffer needs to be before its use by the tasks. Person_Name_Array isn't declared anywhere. (Examples don't have to be entire, but it seems odd that this is the only thing missing. Maybe it's because type declarations can't be nested within protected types, in which case this example could be used to point it out). 10.1.2 In Office.Departments, I'd like a completion for Department, even if only ..., (as done for the other child packages of Office). 11.2 A with and use of Ada.Exceptions would help. (Examples don't have to be entire, but this chapter is specifically about Exceptions, and 11.4.1 is mentioned in a comment, so Ada.Exceptions is something that we're wanting to draw the reader's attention to). 11.4.3 Seems a bit more incomplete than normal, even for just an example. I'd like a declaration of Data_Type and completion of File_Handle in the spec of File_System, a declaration of function File_Exists in the body, and procedure Close in both, even if all are ..., and Verbosity_Desired : Boolean; in main. 12.3 The Matrix used when instantiating Squaring needs to be a definite type (there's no (<>) in the generic declaration in 12.1), but if it's meant to be the type Matrix declared in 3.6 (though it's not said to be) then that won't work as it's indefinite. A.18.32 Not an error, but the "use Adjacency_Lists" in the body is redundant because it’s already in the spec. **************************************************************** From: Randy Brukardt Sent: Monday, April 25, 2016 11:54 PM Here is another "for the record" message; you only need to reply if you object for some reason. In handling Brad's Editorial Reviews, I noted that there was an unhandled cryptic note from Jeff's original message in the part about why we weren't going to add packages to many of these examples: Remove_First's parameter Person should be mode out, not in, to be mode conformant with 3.9.4. That doesn't have anything to do with packages, and clearly should be fixed. After some searching, I found that 8.3.1(12/2) says: overriding procedure Remove_First(Q : in out Security_Queue; Person : in Person_Name); And as Jeff noted, the mode is wrong. (It doesn't match the interface declared in 3.9.4.) So I added a correction to this paragraph to the AI. Consider it my editorial review (or part of Brad's, if you prefer). ****************************************************************