!standard 4.1.3(17/2) 15-10-09 AI12-0178-1/01 !standard 4.3.3(45/2) !standard 4.5.2(37) !standard 9.11(8/2) !standard 12.3(24) !standard 12.7(19/2) !standard 12.7(21/2) !standard 13.5.1(27) !standard B.4(124) !standard B.5(30/3) !standard C.3.2(28/3) !class presentation 15-10-09 !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.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: A : constant String := "A"; "" < A and A < "Aa" -- True A < "Bb" and A < "A " -- True [Editor's note: I think the qualifications Jeff suggested obscure the point of the example. Maybe there is even a better replacement possible??] 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 12.3(24): function Square is new Squaring(Item => Matrix, "*" => Matrix_Product); function Square is new Squaring(Matrix, Matrix_Product); -- same as previous *** Not sure how - no fix in the above *** This is illegal as Matrix (declared in 3.6) is an unconstrained type, and Squaring as declared requires a definite type. But I don't know any sensible fix here, because declaring a constrained matrix subtype alone doesn't work (then the operation would fail subtype conformance and be rejected), and declaring a (sub)type and operation seems like overkill as well as obscuring the actual point of the example. Modify 12.7(19/2): {subtype Key_String is String(1..5);} type String_Id is ... [Editor's note: I changed the name of the string subtype to reflect its use -- might as well promote good practice in examples.] 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 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 := ( others => ... ); !discussion Jeff said: 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. [Editor: No. 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. Maybe we could clarify that somehow, but I don't think there is any point in adding prefixes that would orphan the type declaration in 13.11(39/3). (There is also the question as to whether there should be any prefix in 13.11(41/3) -- probably not. 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.] --------- Jeff said: 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. [Editor: This is true, but it would be a forward reference in the RM (packages haven't been introduced yet), and clearly none of these examples are complete. If we wanted to actually do that, we'd need to move the examples much later in the Standard.] --------- Examples that could be better [Editor: I did nothing with these, I only addressed the examples that were actually wrong. We should discuss whether to change any of these during the upcoming meeting.] 3.6 A definition of type Error_Code would help. [Jeff missed: 3.8 A definition of type Month_Name would help. This was also pointed out in the !appendix of AI05-0248-1.] 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. 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. A.18.32 Not an error, but the "use Adjacency_Lists" in the body is redundant because it’s already in the spec. !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. ****************************************************************