Contents Index Previous Next
7.2 Package Bodies
1
[In contrast to the entities declared in the visible
part of a package, the entities declared in the package_body
are visible only within the package_body
itself. As a consequence, a package with a package_body
can be used for the construction of a group of related subprograms in
which the logical operations available to clients are clearly isolated
from the internal entities.]
Syntax
2
package_body
::=
package body defining_program_unit_name is
declarative_part
[
begin
handled_sequence_of_statements]
end [[
parent_unit_name.]
identifier];
3
If an identifier
or parent_unit_name.identifier
appears at the end of a package_body,
then this sequence of lexical elements shall repeat the defining_program_unit_name.
Legality Rules
4
A
package_body
shall be the completion of a previous
package_declaration
or
generic_package_declaration. A library
package_declaration or library
generic_package_declaration
shall not have a body unless it requires a body[;
pragma Elaborate_Body
can be used to require a
library_unit_declaration
to have a body (see
10.2.1) if it would not otherwise
require one].
4.a
Ramification: The first
part of the rule forbids a package_body
from standing alone -- it has to belong to some previous package_declaration
or generic_package_declaration.
4.b
A nonlibrary package_declaration
or nonlibrary generic_package_declaration
that does not require a completion may have a corresponding body anyway.
Static Semantics
5
In any
package_body
without
statements there is an implicit
null_statement. For any
package_declaration
without an explicit completion, there is an implicit
package_body
containing a single
null_statement. For
a noninstance, nonlibrary package, this body occurs at the end of the
declarative_part
of the innermost enclosing program unit or
block_statement;
if there are several such packages, the order of the implicit
package_bodies
is unspecified.
{unspecified [partial]} [(For
an instance, the implicit
package_body
occurs at the place of the instantiation (see
12.3).
For a library package, the place is partially determined by the elaboration
dependences (see Section 10).)]
5.a
Discussion: Thus, for example,
we can refer to something happening just after the begin of a
package_body, and we can refer to
the handled_sequence_of_statements
of a package_body, without worrying
about all the optional pieces. The place of the implicit body makes a
difference for tasks activated by the package. See also RM83-9.3(5).
5.b
The implicit body would be illegal
if explicit in the case of a library package that does not require (and
therefore does not allow) a body. This is a bit strange, but not harmful.
Dynamic Semantics
6
{elaboration (nongeneric package_body)
[partial]} For the elaboration of a nongeneric
package_body, its
declarative_part
is first elaborated, and its
handled_sequence_of_statements
is then executed.
7
3 A variable declared in
the body of a package is only visible within this body and, consequently,
its value can only be changed within the package_body.
In the absence of local tasks, the value of such a variable remains unchanged
between calls issued from outside the package to subprograms declared
in the visible part. The properties of such a variable are similar to
those of a ``static'' variable of C.
8
4 The elaboration of the body of a
subprogram explicitly declared in the visible part of a package is caused by
the elaboration of the body of the package. Hence a call of such a subprogram
by an outside program unit raises the exception Program_Error if the call takes
place before the elaboration of the package_body
(see 3.11).
Examples
9
Example
of a package body (see 7.1):
10
package body Rational_Numbers is
11
procedure Same_Denominator (X,Y : in out Rational) is
begin
-- reduces X and Y to the same denominator:
...
end Same_Denominator;
12
function "="(X,Y : Rational) return Boolean is
U : Rational := X;
V : Rational := Y;
begin
Same_Denominator (U,V);
return U.Numerator = V.Numerator;
end "=";
13
function "/" (X,Y : Integer) return Rational is
begin
if Y > 0 then
return (Numerator => X, Denominator => Y);
else
return (Numerator => -X, Denominator => -Y);
end if;
end "/";
14
function "+" (X,Y : Rational) return Rational is ... end "+";
function "-" (X,Y : Rational) return Rational is ... end "-";
function "*" (X,Y : Rational) return Rational is ... end "*";
function "/" (X,Y : Rational) return Rational is ... end "/";
15
end Rational_Numbers;
Wording Changes from Ada 83
15.a
The syntax rule for package_body
now uses the syntactic category handled_sequence_of_statements.
15.b
The declarative_part
of a package_body is now required;
that doesn't make any real difference, since a declarative_part
can be empty.
15.c
RM83 seems to have forgotten to
say that a package_body can't stand
alone, without a previous declaration. We state that rule here.
15.d
RM83 forgot to restrict the definition
of elaboration of package_bodies
to nongeneric ones. We have corrected that omission.
15.e
The rule about implicit bodies
(from RM83-9.3(5)) is moved here, since it is more generally applicable.
Contents Index Previous Next Legal