5.6 Block Statements
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
[A block_statement
encloses a handled_sequence_of_statements
optionally preceded by a declarative_part
.]
Syntax
2block_statement
::=
[block_statement_identifier
:]
[declare
declarative_part
]
begin
handled_sequence_of_statements
end [block_identifier
];
3
If a block_statement
has a block_statement_identifier
, then the identifier
shall be repeated after the end; otherwise, there shall not be an identifier
after the end.
Static Semantics
4A block_statement
that has no explicit declarative_part
has an implicit empty declarative_part
.
Thus, other rules can always refer to the declarative_part
of a block_statement
.
Dynamic Semantics
5The execution of a block_statement
consists of the elaboration of its declarative_part
followed by the execution of its handled_sequence_of_statements
.
Examples
6Example of a block statement with a local variable:
Swap:
declare
Temp : Integer;
begin
Temp := V; V := U; U := Temp;
end Swap;
If task objects are declared within a block_statement
whose execution is completed, the block_statement
is not left until all its dependent tasks are terminated (see 7.6). This rule applies to completion caused by a transfer of control.
Within a block_statement
, the block name can be used in expanded names denoting local entities such as Swap.Temp in the above example (see 4.1.3).
Wording Changes from Ada 83
The syntax rule for block_statement
now uses the syntactic category handled_sequence_of_statements
.
5.6.1 Parallel Block Statements
1/5[A parallel_block_statement
comprises two or more sequence_of_statements
separated by and where each represents an independent activity that is intended to proceed concurrently with the others.]
Syntax
2/5parallel_block_statement
::=
parallel [(chunk_specification
)] [aspect_specification
] do
sequence_of_statements
and
sequence_of_statements
{and
sequence_of_statements
}
end do;
3/5
The chunk_specification
, if any, of a parallel_block_statement
shall be an integer_simple_expression
.
Dynamic Semantics
4/5For the execution of a parallel_block_statement
, the chunk_specification
and the aspect_specification
, if any, are elaborated in an arbitrary order. After elaborating the chunk_specification
, if any, a check is made that the determined maximum number of chunks is greater than zero. If this check fails, Program_Error is raised.
Then, the various sequence_of_statements
are grouped into one or more chunks, each with its own logical thread of control (see Clause 9), up to the maximum number of chunks specified by the chunk_specification
, if any. Within each chunk every sequence_of_statements
of the chunk is executed in turn, in an arbitrary order. The parallel_block_statement
is complete once every one of the sequence_of_statements
has completed, either by reaching the end of its execution, or due to a transfer of control out of the construct by one of the sequence_of_statements
(see 5.1).
Although each sequence_of_statements
of a parallel block represents a separate logical thread of control, the implementation may choose to combine two or more such logical threads of control into a single physical thread of control to reduce the cost of creating numerous physical threads of control.
Examples
6/5Example of a parallel block used to walk a binary tree in parallel:
procedure Traverse (T : Expr_Ptr) is -- see 3.9.1
begin
if T /= null and then
T.all in Binary_Operation'Class -- see 3.9.1
then -- recurse down the binary tree
parallel do
Traverse (T.Left);
and
Traverse (T.Right);
and
Ada.Text_IO.Put_Line
("Processing " & Ada.Tags.Expanded_Name (T'Tag));
end do;
end if;
end Traverse;
8/5
Example of a parallel block used to search two halves of a string in parallel:
function Search (S : String; Char : Character) return Boolean is
begin
if S'Length <= 1000 then
-- Sequential scan
return (for some C of S => C = Char);
else
-- Parallel divide and conquer
declare
Mid : constant Positive := S'First + S'Length/2 - 1;
begin
parallel do
for C of S(S'First .. Mid) loop
if C = Char then
return True; -- Terminates enclosing do
end if;
end loop;
and
for C of S(Mid + 1 .. S'Last) loop
if C = Char then
return True; -- Terminates enclosing do
end if;
end loop;
end do;
-- Not found
return False;
end;
end if;
end Search;