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

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

!standard 4.1.3(17/2)          15-11-18 AI12-0178-1/02
!standard 4.3.2(13)
!standard 4.3.3(45/2)
!standard 4.5.2(37)
!standard 9.11(8/2)
!standard 10.1.2(29/2)
!standard 11.2(12)
!standard 11.4.3(5/2)
!standard 11.4.3(6/2)
!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 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'(}1.2{)}, Right => {new Literal'(}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:
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 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(5/2):
... {private
...}
end File_System;
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.]
[Note: This ... provides a place for File_Exists to be declared.]
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 ...
[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 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 := ( 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 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.
!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