Version 1.1 of ais/ai-00433.txt
!standard 2.8(29) 05-05-18 AI95-00433/01
!standard 3.2.2(15)
!standard 3.3.1(27)
!standard 3.3.1(29)
!standard 3.3.1(31)
!standard 3.3.1(33)
!standard 3.6(30)
!standard 3.7(37)
!standard 3.9.2(14)
!standard 3.10(22)
!standard 3.10.1(19)
!standard 3.10.1(20)
!standard 3.10.1(21)
!standard 4.3.3(43)
!standard 6.5.1(9)
!standard 6.7(4)
!standard 9.1(24)
!standard 9.11(3)
!standard 9.11(6)
!standard 9.11(7)
!standard 9.11(8)
!standard 9.11(9)
!standard 9.11(10)
!standard 10.1.2(24)
!standard 11.3(6)
!standard 12.5.5(5)
!standard 12.6(18)
!standard 12.7(11)
!class amendment 05-05-18
!status Amendment 200Y 05-05-18
!status work item 05-05-18
!status received 05-05-18
!priority High
!difficulty Easy
!subject Examples in the RM
!summary
(See proposal.)
!problem
The examples in the RM must be updated to reflect the new language.
!proposal
Tuck did the examples in a stream-of-consciousness manner, and Pascal got the
short stick to write an AI.
!wording
(See corrigendum.)
!discussion
(See proposal.)
!example
An example for examples? Get real!
!corrigendum 2.8(29)
Replace the paragraph:
pragma List(Off); -- turn off listing generation
pragma Optimize(Off); -- turn off optional optimizations
pragma Inline(Set_Mask); -- generate code for Set_Mask inline
pragma Suppress(Range_Check, On => Index); -- turn off range checking on Index
by:
pragma List(Off); -- turn off listing generation
pragma Optimize(Off); -- turn off optional optimizations
pragma Inline(Set_Mask); -- generate code for Set_Mask inline
pragma Import(C, Put_Char, External_Name => "putchar"); -- import C putchar function
!corrigendum 3.2.2(15)
Replace the paragraph:
subtype Rainbow is Color range Red .. Blue; -- see 3.2.1
subtype Red_Blue is Rainbow;
subtype Int is Integer;
subtype Small_Int is Integer range -10 .. 10;
subtype Up_To_K is Column range 1 .. K; -- see 3.2.1
subtype Square is Matrix(1 .. 10, 1 .. 10); -- see 3.6
subtype Male is Person(Sex => M); -- see 3.10.1
by:
subtype Rainbow is Color range Red .. Blue; -- see 3.2.1
subtype Red_Blue is Rainbow;
subtype Int is Integer;
subtype Small_Int is Integer range -10 .. 10;
subtype Up_To_K is Column range 1 .. K; -- see 3.2.1
subtype Square is Matrix(1 .. 10, 1 .. 10); -- see 3.6
subtype Male is Person(Sex => M); -- see 3.10.1
subtype Binop_Ref is not null Binop_Ptr; -- see 3.10
!corrigendum 3.3.1(27)
Replace the paragraph:
John, Paul : Person_Name := new Person(Sex => M); -- see 3.10.1
by:
John, Paul : not null Person_Name := new Person(Sex => M); -- see 3.10.1
!corrigendum 3.3.1(29)
Replace the paragraph:
John : Person_Name := new Person(Sex => M);
Paul : Person_Name := new Person(Sex => M);
by:
John : not null Person_Name := new Person(Sex => M);
Paul : not null Person_Name := new Person(Sex => M);
!corrigendum 3.3.1(31)
Replace the paragraph:
Count, Sum : Integer;
Size : Integer range 0 .. 10_000 := 0;
Sorted : Boolean := False;
Color_Table : array(1 .. Max) of Color;
Option : Bit_Vector(1 .. 10) := (others => True);
Hello : constant String := "Hi, world.";
by:
Count, Sum : Integer;
Size : Integer range 0 .. 10_000 := 0;
Sorted : Boolean := False;
Color_Table : array(1 .. Max) of Color;
Option : Bit_Vector(1 .. 10) := (others => True);
Hello : aliased String := "Hi, world.";
!corrigendum 3.3.1(33)
Replace the paragraph:
Limit : constant Integer := 10_000;
Low_Limit : constant Integer := Limit/10;
Tolerance : constant Real := Dispersion(1.15);
by:
Limit : constant Integer := 10_000;
Low_Limit : constant Integer := Limit/10;
Tolerance : constant Real := Dispersion(1.15);
Hello_Msg : constant access String := Hello'Access; -- see 3.10.2
!corrigendum 3.6(30)
Replace the paragraph:
Grid : array(1 .. 80, 1 .. 100) of Boolean;
Mix : array(Color range Red .. Green) of Boolean;
Page : array(Positive range <>) of Line := -- an array of arrays
(1 | 50 => Line'(1 | Line'Last => '+', others => '-'), -- see 4.3.3
2 .. 49 => Line'(1 | Line'Last => '|', others => ' '));
-- Page is constrained by its initial value to (1..50)
by:
Grid : array(1 .. 80, 1 .. 100) of Boolean;
Mix : array(Color range Red .. Green) of Boolean;
Msg_Table : constant array(Error_Code) of access constant String :=
(Too_Big => new String'("Result too big"), Too_Small => ...);
Page : array(Positive range <>) of Line := -- an array of arrays
(1 | 50 => Line'(1 | Line'Last => '+', others => '-'), -- see 4.3.3
2 .. 49 => Line'(1 | Line'Last => '|', others => ' '));
-- Page is constrained by its initial value to (1..50)
!corrigendum 3.7(37)
Replace the paragraph:
type Item(Number : Positive) is
record
Content : Integer;
-- no component depends on the discriminant
end record;
by:
task type Worker(Prio : System.Priority; Buf : access Buffer) is
-- discriminants used to parameterize the task type (see 9.1)
pragma Priority(Prio); -- see D.1
entry Fill;
entry Drain;
end Worker;
!corrigendum 3.9.2(14)
Insert after the paragraph:
Nonlimited interface types have predefined nonabstract equality operators. These may be overridden with user-defined abstract equality operators. Such operators will then require an explicit overriding for any nonabstract descendant of the interface.
the new paragraphs:
Examples
Example of limited interface and synchronized interface extending it:
type Queue is limited interface;
procedure Append(Q : in out Queue; Elem : in Element) is abstract;
procedure Remove_First(Q : in out Queue; Elem : out Element) is abstract;
function Cur_Count(Q : in Queue) return Natural is abstract;
function Max_Count(Q : in Queue) return Natural is abstract;
Queue_Error : exception;
-- Append raises Queue_Error if Count(Q) = Max_Count(Q)
-- Remove_First raises Queue_Error if Count(Q) = 0
type Synchronized_Queue is synchronized interface and Queue; -- see 9.11
procedure Append_Wait(Q : in out Queue; Elem : in Element) is abstract;
procedure Remove_First_Wait(Q : in out Queue; Elem : out Element) is abstract;
...
procedure Transfer(From : in out Queue'Class;
To : in out Queue'Class;
Number : in Natural := 1) is
Elem : Element;
begin
for I in 1..Number loop
Remove_First(From, Elem);
Append(To, Elem);
end loop;
end Transfer;
The Queue interface has four dispatching operations, Append,
Remove_First, Cur_Count, and Max_Count. The body of a class-wide
operation, Transfer is also shown. Every non-abstract extension
of Queue must provide implementations for at least its four
dispatching operations. Any object of a type derived from Queue
may be passed to Transfer, as either the From or the To operand.
The two operands need not be of the same type in any given call.
The Synchronized_Queue interface inherits the four dispatching
operations from Queue, and adds two additional dispatching
operations, which wait if necessary rather than raising the
Queue_Error exception. This synchronized interface may only
be implemented by a task or protected type, and as such
ensures safe concurrent access.
Example of task interface:
type Serial_Device is task interface; -- see 9.1
procedure Read (Dev : in Serial_Device; C : out Character) is abstract;
procedure Write(Dev : in Serial_Device; C : in Character) is abstract;
The Serial_Device interface has two dispatching operations
which are intended to be implemented using task entries (see 9.1).
!corrigendum 3.10(22)
Replace the paragraph:
type Peripheral_Ref is access Peripheral; -- see 3.8.1
type Binop_Ptr is access all Binary_Operation'Class;
-- general access-to-class-wide, see 3.9.1
by:
type Peripheral_Ref is not null access Peripheral; -- see 3.8.1
type Binop_Ptr is access all Binary_Operation'Class;
-- general access-to-class-wide, see 3.9.1
!corrigendum 3.10.1(19)
Replace the paragraph:
type Person(<>); -- incomplete type declaration
type Car; -- incomplete type declaration
by:
type Person(<>); -- incomplete type declaration
type Car is tagged; -- incomplete type declaration
!corrigendum 3.10.1(20)
Replace the paragraph:
type Person_Name is access Person;
type Car_Name is access all Car;
by:
type Person_Name is access Person;
type Car_Name is access all Car'Class;
!corrigendum 3.10.1(21)
Replace the paragraph:
type Car is
record
Number : Integer;
Owner : Person_Name;
end record;
by:
type Car is tagged
record
Number : Integer;
Owner : Person_Name;
end record;
!corrigendum 4.3.3(43)
Insert after the paragraph:
D : Bit_Vector(M .. N) := (M .. N => True); -- see 3.6
E : Bit_Vector(M .. N) := (others => True);
F : String(1 .. 1) := (1 => 'F'); -- a one component aggregate: same as "F"
the new paragraphs:
Example of array aggregate with defaulted others choice, with applicable index constraint provided by an enclosing record aggregate:
Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- see 3.7
!corrigendum 6.5.1(9)
Insert after the paragraph:
If the body of a non-returning procedure completes normally, Program_Error is raised at the point of the call.
the new paragraphs:
Example
procedure Fail(Msg : String); -- raises Fatal_Error exception
pragma No_Return(Fail);
-- Inform compiler and reader that procedure never returns normally
!corrigendum 6.7(4)
Insert after the paragraph:
The execution of a null procedure is invoked by a subprogram call. For the execution of a subprogram call on a null procedure, the execution of the subprogram_body has no effect.
the new paragraph:
Example
procedure Simplify(Expr : in out Expression) is null; -- see 3.9
-- By default, Simplify does nothing, but it may be overridden in extensions of Expression
!corrigendum 9.1(24)
Replace the paragraph:
task type Keyboard_Driver(ID : Keyboard_ID := New_ID) is
entry Read (C : out Character);
entry Write(C : in Character);
end Keyboard_Driver;
by:
task type Keyboard_Driver(ID : Keyboard_ID := New_ID) is
new Serial_Device with -- see 3.9
entry Read (C : out Character);
entry Write(C : in Character);
end Keyboard_Driver;
!corrigendum 9.11(3)
Replace the paragraph:
task body Producer is
Char : Character;
begin
loop
... -- produce the next character Char
Buffer.Write(Char);
exit when Char = ASCII.EOT;
end loop;
end Producer;
by:
task body Producer is
Elem : Element;
begin
loop
... -- produce the next element
Buffer.Append_Wait(Elem);
exit when Elem = EOT_Elem;
end loop;
end Producer;
!corrigendum 9.11(6)
Replace the paragraph:
task body Consumer is
Char : Character;
begin
loop
Buffer.Read(Char);
exit when Char = ASCII.EOT;
... -- consume the character Char
end loop;
end Consumer;
by:
task body Consumer is
Elem : Element;
begin
loop
Buffer.Remove_First_Wait(Elem);
exit when Elem = EOT_Elem;
... -- consume the element
end loop;
end Consumer;
!corrigendum 9.11(7)
Replace the paragraph:
The buffer object contains an internal pool of characters managed in a round-robin fashion. The pool has two indices, an In_Index denoting the space for the next input character and an Out_Index denoting the space for the next output character.
by:
The buffer object contains an internal pool of elements managed in a round-robin fashion. The pool has two indices, an In_Index denoting the space for the next input element and an Out_Index denoting the space for the next output element.
The Buffer is defined as an extension of the Synchronized_Queue
interface (see 3.9.4), and as such, can be passed to the Transfer
class-wide operation defined for objects of a type covered by
Queue'Class.
!corrigendum 9.11(8)
Replace the paragraph:
protected Buffer is
entry Read (C : out Character);
entry Write(C : in Character);
private
Pool : String(1 .. 100);
Count : Natural := 0;
In_Index, Out_Index : Positive := 1;
end Buffer;
by:
protected Buffer is new Synchronized_Queue with -- see 3.9.4
entry Append_Wait (Elem : in Element);
entry Remove_First_Wait (Elem : out Element);
function Cur_Count return Natural;
function Max_Count return Natural;
procedure Append(Elem : in Element);
procedure Remove_First(Elem : out Element);
private
Pool : Element_Array(1 .. 100);
Count : Natural := 0;
In_Index, Out_Index : Positive := 1;
end Buffer;
!corrigendum 9.11(9)
Replace the paragraph:
protected body Buffer is
entry Write(C : in Character)
when Count < Pool'Length is
begin
Pool(In_Index) := C;
In_Index := (In_Index mod Pool'Length) + 1;
Count := Count + 1;
end Write;
by:
protected body Buffer is
entry Append_Wait (Elem : in Element)
when Count < Pool'Length is
begin
Append(Elem);
end Append_Wait;
procedure Append(Elem : in Element) is
begin
if Count = Pool'Length then
raise Queue_Error with "Buffer Full"; -- see 11.3
end if;
Pool(In_Index) := Elem;
In_Index := (In_Index mod Pool'Length) + 1;
Count := Count + 1;
end Append;
!corrigendum 9.11(10)
Replace the paragraph:
entry Read(C : out Character)
when Count > 0 is
begin
C := Pool(Out_Index);
Out_Index := (Out_Index mod Pool'Length) + 1;
Count := Count - 1;
end Read;
end Buffer;
by:
entry Remove_First_Wait (Elem : out Element)
when Count > 0 is
begin
Remove_First(Elem);
end Remove_First_Wait;
procedure Remove_First(Elem : out Element) is
begin
if Count = 0 then
raise Queue_Error with "Buffer Empty"; -- see 11.3
end if;
Elem := Pool(Out_Index);
Out_Index := (Out_Index mod Pool'Length) + 1;
Count := Count - 1;
end Remove_First;
function Cur_Count return Natural is
begin
return Buffer.Count;
end Cur_Count;
function Max_Count return Natural is
begin
return Pool'Length;
end Max_Count;
end Buffer;
!corrigendum 10.1.2(24)
Insert after the paragraph:
- in the scope of a use_clause which names an entity declared
within the declarative region of the library_item.
the new paragraphs:
Example
limited with Office.Departments; -- types are incomplete
private with Office.Locations; -- only visible in private part
package Office.Employees is
type Employee is private;
function Dept_Of(Emp : Employee) return access Departments.Department;
procedure Assign_Dept(Emp : in out Employee;
Dept : access Departments.Department);
...
private
type Employee is
record
Dept : access Departments.Department;
Loc : Locations.Location;
...
end record;
end Office.Employees;
limited with Office.Employees;
package Office.Departments is
type Department is private;
function Manager_Of(Dept : Department) return access Employees.Employee;
procedure Assign_Manager(Dept : in out Department;
Mgr : access Employees.Employee);
...
end Office.Departments;
The limited_with_clause may be used to support mutually dependent
abstractions that are split across multiple packages. In this
case, an employee is assigned to a department, and a department has
a manager who is an employee. If a with_clause with the reserved
word private appears on one library unit and mentions a second
library unit, it provides visibility to the second library unit, but
restricts that visibility to the private part and body of the first
unit. The compiler checks that no use is made of the second unit in
the visible part of the first unit.
!corrigendum 11.3(6)
Replace the paragraph:
raise Ada.IO_Exceptions.Name_Error; -- see A.13
by:
raise Ada.IO_Exceptions.Name_Error; -- see A.13
raise Queue_Error with "Buffer Full"; -- see 9.11
!corrigendum 12.5.5(5)
Insert after the paragraph:
The actual type shall be a limited, task, protected, or synchronized interface if and only if the formal type is also, respectively, a limited, task, protected, or synchronized interface.
the new paragraphs:
Example
generic
type Managed_Task is task interface;
type Work_Item(<>) is new Root_Work_Item with private;
package Server_Manager is
task type Server is new Managed_Task with
entry Start(Data : access Work_Item);
end Server;
end Server_Manager;
This generic allows an application to establish a standard interface
that all tasks need to implement so they can be managed appropriately
by an application-specific scheduler.
!corrigendum 12.6(18)
Replace the paragraph:
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
by:
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
with procedure Pre_Action(X : in Item) is null; -- defaults to no action
with procedure Write(S : access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; -- see 13.13.2
-- Dispatching operation on Descriptor with default
!corrigendum 12.7(11)
Insert after the paragraph:
For the purposes of matching, if the actual instance A is itself a
formal package, then the actual parameters of A are those specified
explicitly or implicitly in the formal_package_actual_part for A, plus,
for those not specified, the copies of the formal parameters of the
template included in the visible part of A.
the new paragraphs:
Examples
Example of generic package with formal package parameters:
generic
with package Mapping_1 is new Generic_Mapping(<>);
with package Mapping_2 is new Generic_Mapping
(Key_Type => Mapping_1.Element_Type,
others => <>);
package Generic_Join is
-- Provide a "join" between two mappings
subtype Key_Type is Mapping_1.Key_Type;
subtype Element_Type is Mapping_2.Element_Type;
function Lookup(Key : Key_Type) return Element_Type;
...
end Generic_Join;
Example of instantiation of package with formal packages:
package String_Table is new Generic_Mapping(Key_Type => String,
Element_Type => String_ID);
package Symbol_Table is new Generic_Mapping(Key_Type => String_ID,
Element_Type => Symbol_Info);
package String_Info is new Generic_Join(Mapping_1 => String_Table,
Mapping_2 => Symbol_Table);
Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
!ACATS test
This one is going to be hard to test!
!appendix
****************************************************************
Questions? Ask the ACAA Technical Agent