Version 1.6 of ai12s/ai12-0178-1.txt

Unformatted version of ai12s/ai12-0178-1.txt version 1.6
Other versions for file ai12s/ai12-0178-1.txt

!standard 4.1.3(17/2)          16-03-30 AI12-0178-1/03
!standard 4.3.2(13)
!standard 4.3.3(45/2)
!standard 4.5.2(37)
!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 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 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
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 shouldn't be any prefix in 13.11(41/3).)
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 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)
Replace:
Pool(K).Write -- an entry of the task Pool(K) (see 9.4)
by:
Pool(K).Write -- an entry of the task Pool(K) (see 9.1)
!corrigendum 4.3.2(13)
Replace the paragraph:
(Expression with Left => 1.2, Right => 3.4) Addition'(Binop with null record) -- presuming Binop is of type Binary_Operation
by:
(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
!corrigendum 4.3.3(45/2)
Replace the paragraph:
Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- see 3.7
by:
Buffer'(Size => 50, Pos => 1, Value => ('x', others => <>)) -- see 3.7
!corrigendum 4.5.2(37)
Replace the paragraph:
"" < "A" and "A" < "Aa" -- True "Aa" < "B" and "A" < "A " -- True
by:
S : String := "A"; "" < S and S < "Aa" -- True S < "Bb" and S < "A " -- True
!corrigendum 9.7.3(6)
Replace:
procedure Spin(R : in Resource) is
by:
procedure Spin(R : in out Resource) is -- see 9.4
!corrigendum 9.11(7.1/2)
Insert after the paragraph:
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.
the new paragraph:
type Person_Name_Array is array (Positive range <>) of Person_Name; -- see 3.10.1
!corrigendum 10.1.2(29/2)
Replace the paragraph:
limited with Office.Employees; package Office.Departments is type Department is private;
by:
limited with Office.Employees; package Office.Departments is type Department is ...;
!corrigendum 11.2(12)
Replace the paragraph:
begin Open(File, In_File, "input.txt"); -- see A.8.2 exception when E : Name_Error => Put("Cannot open input file : "); Put_Line(Exception_Message(E)); -- see 11.4.1 raise; end;
by:
begin Open(File, In_File, "input.txt"); -- see A.8.2 exception when E : Name_Error => Put("Cannot open input file : "); Put_Line(Ada.Exceptions.Exception_Message(E)); -- see 11.4.1 raise; end;
!corrigendum 11.4.3(2/2)
Replace the paragraph:
package File_System is type File_Handle is limited private;
by:
package File_System is type Data_Type is ...; type File_Handle is limited private;
!corrigendum 11.4.3(5)
Replace the paragraph:
... end File_System;
by:
... private ... end File_System;
package body File_System is ...
!corrigendum 11.4.3(6/2)
Replace the paragraph:
package body File_System is procedure Open(F : in out File_Handle; Name : String) is begin if File_Exists(Name) then ... else raise File_Not_Found with "File not found: " & Name & "."; end if; end Open;
by:
procedure Open(F : in out File_Handle; Name : String) is begin if File_Exists(Name) then ... else raise File_Not_Found with "File not found: " & Name & "."; end if; end Open;
!corrigendum 11.4.3(10)
Replace:
with Ada.Text_IO; with Ada.Exceptions; with File_System; use File_System; use Ada; procedure Main is begin
by:
with Ada.Text_IO; with Ada.Exceptions; with File_System; use File_System; use Ada; procedure Main is Verbosity_Desired : Boolean := ...; begin
!corrigendum 12.1(22)
Replace the paragraph:
generic type Item is private; with function "*"(U, V : Item) return Item is <>; function Squaring(X : Item) return Item;
by:
generic type Item (<>) is private; with function "*"(U, V : Item) return Item is <>; function Squaring(X : Item) return Item;
!corrigendum 12.3(24)
Replace the paragraph:
procedure Swap is new Exchange(Elem => Integer); procedure Swap is new Exchange(Character); -- Swap is overloaded function Square is new Squaring(Integer); -- "*" of Integer used by default function Square is new Squaring(Item => Matrix, "*" => Matrix_Product); function Square is new Squaring(Matrix, Matrix_Product); -- same as previous
by:
procedure Swap is new Exchange(Elem => Integer); procedure Swap is new Exchange(Character); -- Swap is overloaded function Square is new Squaring(Integer); -- "*" of Integer used by default function Square1 is new Squaring(Item => Matrix, "*" => Matrix_Product); function Square2 is new Squaring(Matrix, Matrix_Product); -- same as previous
!corrigendum 12.7(19/2)
Replace the paragraph:
type String_Id is ...
by:
subtype Key_String is String(1..5); type String_Id is ...
!corrigendum 12.7(21/2)
Replace the paragraph:
package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => String, Element_Type => String_Id);
by:
package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => Key_String, Element_Type => String_Id);
!corrigendum 13.5.1(27)
Replace the paragraph:
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;
by:
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;
!corrigendum 13.11(41/3)
Replace the paragraph:
Our_Pool : Mark_Release_Pool_Type (Pool_Size => 2000); My_Mark : MR_Pool.Subpool_Handle; -- See 13.11.6
by:
Our_Pool : Mark_Release_Pool_Type (Pool_Size => 2000); My_Mark : Subpool_Handle; -- As declared in 13.11.6
!corrigendum A.18.32(9/3)
Replace the paragraph:
package body Shortest_Paths is function Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) return Paths.List is use Adjacency_Lists, Node_Maps, Paths, Graphs; Reached : array (Node) of Boolean := (others => False); -- The set of nodes whose shortest distance to the source is known.
by:
package body Shortest_Paths is function Shortest_Path (G : Graphs.Vector; Source : Node; Target : Node) return Paths.List is use Node_Maps, Paths, Graphs; Reached : array (Node) of Boolean := (others => False); -- The set of nodes whose shortest distance to the source is known.
!corrigendum B.4(124)
Replace the paragraph:
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); ... -- Process Ada_Record end loop; exception when End_Error => ... end Test_External_Formats;
by:
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); ... -- Process Ada_Record end loop; exception when End_Error => ... end Test_External_Formats;
!corrigendum B.5(30/3)
Replace the paragraph:
type Fortran_Matrix is array (Integer range <>, Integer range <>) of Double_Precision with Convention => Fortran; -- stored in Fortran's -- column-major order procedure Invert (Rank : in Fortran_Integer; X : in out Fortran_Matrix) with Import => True, Convention => Fortran; -- a Fortran subroutine
by:
type Fortran_Matrix is array (Fortran_Integer range <>, Fortran_Integer range <>) of Double_Precision with Convention => Fortran; -- stored in Fortran's -- column-major order procedure Invert (Rank : in Fortran_Integer; X : in out Fortran_Matrix) with Import => True, Convention => Fortran; -- a Fortran subroutine
!corrigendum C.3.2(28/3)
Replace:
Device_Priority : constant array (1..5) of System.Interrupt_Priority := ( ... );
by:
Device_Priority : constant array (Ada.Interrupts.Interrupt_Id range 1..5) of 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.

****************************************************************

Questions? Ask the ACAA Technical Agent