[Home] [Prev] [Next] [Index]

6.3 Subprogram Bodies

6.3 Subprogram Bodies

1
[A subprogram_body specifies the execution of a subprogram.]

Syntax

2
subprogram_body ::=
    subprogram_specification is
       declarative_part
    begin
        handled_sequence_of_statements
    end [designator];

3
If a designator appears at the end of a subprogram_body, it shall repeat the defining_designator of the subprogram_specification.

Legality Rules

4
[In contrast to other bodies, ] a subprogram_body need not be the completion of a previous declaration[, in which case the body declares the subprogram]. If the body is a completion, it shall be the completion of a subprogram_declaration or generic_subprogram_declaration. The profile of a subprogram_body that completes a declaration shall conform fully to that of the declaration.

Static Semantics

5
A subprogram_body is considered a declaration. It can either complete a previous declaration, or itself be the initial declaration of the subprogram.

Dynamic Semantics

6
The elaboration of a non-generic subprogram_body has no other effect than to establish that the subprogram can from then on be called without failing the Elaboration_Check.

6.a
Ramification: See 12.2 for elaboration of a generic body. Note that protected subprogram_bodies never get elaborated; the elaboration of the containing protected_body allows them to be called without failing the Elaboration_Check.

7
[The execution of a subprogram_body is invoked by a subprogram call.] For this execution the declarative_part is elaborated, and the handled_sequence_of_statements is then executed.

Examples

8
Example of procedure body:

9
procedure Push(E : in Element_Type; S : in out Stack) is
begin
   if S.Index = S.Size then
      raise Stack_Overflow;
   else
      S.Index := S.Index + 1;
      S.Space(S.Index) := E;
   end if;
end Push;

10
Example of a function body:

11
function Dot_Product(Left, Right : Vector) return Real is
   Sum : Real := 0.0;
begin
   Check(Left'First = Right'First and Left'Last = Right'Last);
   for J in Left'Range loop
      Sum := Sum + Left(J)*Right(J);
   end loop;
   return Sum;
end Dot_Product;

Extensions to Ada 83

11.a
A renaming_declaration may be used instead of a subprogram_body.

Wording Changes From Ada 83

11.b
The syntax rule for subprogram_body now uses the syntactic category handled_sequence_of_statements.

11.c
The declarative_part of a subprogram_body is now required; that doesn't make any real difference, because a declarative_part can be empty.

11.d
We have incorporated some rules from RM83-6.5 here.

11.e
RM83 forgot to restrict the definition of elaboration of a subprogram_body to non-generics.

6.3.1 Conformance Rules

1
[When subprogram profiles are given in more than one place, they are required to conform in one of four ways: type conformance, mode conformance, subtype conformance, or full conformance.]

Static Semantics

2
[As explained in B.1, "Interfacing Pragmas", a convention can be specified for an entity. For a callable entity or access-to-subprogram type, the convention is called the calling convention.] The following conventions are defined by the language:

3 ·
The default calling convention for any subprogram not listed below is Ada. [A pragma Convention, Import, or Export may be used to override the default calling convention (see B.1)].

3.a
Ramification: See also the rule about renamings-as-body in 8.5.4.

4 ·
The Intrinsic calling convention represents subprograms that are "built in" to the compiler. The default calling convention is Intrinsic for the following:

5 ·   
an enumeration literal;
6 ·   
a "/=" operator declared implicitly due to the declaration of "=" (see 6.6);
7 ·   
any other implicitly declared subprogram unless it is a dispatching operation of a tagged type;
8 ·   
an inherited subprogram of a generic formal tagged type with unknown discriminants;
9 ·   
an attribute that is a subprogram;
10 ·   
a subprogram declared immediately within a protected_body.
11
[The Access attribute is not allowed for Intrinsic subprograms.]

11.a
Ramification: The Intrinsic calling convention really represents any number of calling conventions at the machine code level; the compiler might have a different instruction sequence for each intrinsic. That's why the Access attribute is disallowed. We do not wish to require the implementation to generate an out of line body for an intrinsic.

11.b
Whenever we wish to disallow the Access attribute in order to ease implementation, we make the subprogram Intrinsic. Several language-defined subprograms have "pragma Convention(Intrinsic, ...);". An implementation might actually implement this as "pragma Import(Intrinsic, ...);", if there is really no body, and the implementation of the subprogram is built into the code generator.

11.c
Subprograms declared in protected_bodies will generally have a special calling convention so as to pass along the identification of the current instance of the protected type. The convention is not protected since such local subprograms need not contain any "locking" logic since they are not callable via "external" calls; this rule prevents an access value designating such a subprogram from being passed outside the protected unit.

11.d
The "implicitly declared subprogram" above refers to predefined operators (other than the "=" of a tagged type) and the inherited subprograms of untagged types.

12 ·
The default calling convention is protected for a protected subprogram, and for an access-to-subprogram type with the reserved word protected in its definition.

13 ·
The default calling convention is entry for an entry.

14
Of these four conventions, only Ada and Intrinsic are allowed as a convention_identifier in a pragma Convention, Import, or Export.

14.a
Discussion:  The names of the protected and entry calling conventions cannot be used in the interfacing pragmas. Note that protected and entry are reserved words.

15
Two profiles are type conformant if they have the same number of parameters, and both have a result if either does, and corresponding parameter and result types are the same, or, for access parameters, corresponding designated types are the same.

15.a
Discussion:  For access parameters, the designated types have to be the same for type conformance, not the access types, since in general each access parameter has its own anonymous access type, created when the subprogram is called. Of course, corresponding parameters have to be either both access parameters or both not access parameters.

16
Two profiles are mode conformant if they are type-conformant, and corresponding parameters have identical modes, and, for access parameters, the designated subtypes statically match.

17
Two profiles are subtype conformant if they are mode-conformant, corresponding subtypes of the profile statically match, and the associated calling conventions are the same. The profile of a generic formal subprogram is not subtype-conformant with any other profile.

17.a
Ramification:

18
Two profiles are fully conformant if they are subtype-conformant, and corresponding parameters have the same names and have default_expressions that are fully conformant with one another.

18.a
Ramification: Full conformance requires subtype conformance, which requires the same calling conventions. However, the calling convention of the declaration and body of a subprogram or entry are always the same by definition.

19
Two expressions are fully conformant if, [after replacing each use of an operator with the equivalent function_call:]

20 ·
each constituent construct of one corresponds to an instance of the same syntactic category in the other, except that an expanded name may correspond to a direct_name (or character_literal) or to a different expanded name in the other; and

21 ·
each direct_name, character_literal, and selector_name that is not part of the prefix of an expanded name in one denotes the same declaration as the corresponding direct_name, character_literal, or selector_name in the other; and

21.a
Ramification: Note that it doesn't say "respectively" because a direct_name can correspond to a selector_name, and vice-versa, by the previous bullet. This rule allows the prefix of an expanded name to be removed, or replaced with a different prefix that denotes a renaming of the same entity. However, it does not allow a direct_name or selector_name to be replaced with one denoting a distinct renaming (except for direct_names and selector_names in prefixes of expanded names). Note that calls using operator notation are equivalent to calls using prefix notation.

21.b
Given the following declarations:

21.c
package A is
    function F(X : Integer := 1) return Boolean;
end A;

21.d
with A;
package B is
    package A_View renames A;
    function F_View(X : Integer := 9999) return Boolean renames F;
end B;

21.e
with A, B; use A, B;
procedure Main is ...

21.f
Within Main, the expressions "F", "A.F", "B.A_View.F", and "A_View.F" are all fully conformant with one another. However, "F" and "F_View" are not fully conformant. If they were, it would be bad news, since the two denoted views have different default_expressions.

22 ·
each primary that is a literal in one has the same value as the corresponding literal in the other.

22.a
Ramification: The literals may be written differently.

22.b
Ramification: Note that the above definition makes full conformance a transitive relation.

23
Two known_discriminant_parts are fully conformant if they have the same number of discriminants, and discriminants in the same positions have the same names, statically matching subtypes, and default_expressions that are fully conformant with one another.

24
Two discrete_subtype_definitions are fully conformant if they are both subtype_indications or are both ranges, the subtype_marks (if any) denote the same subtype, and the corresponding simple_expressions of the ranges (if any) fully conform.

24.a
Ramification: In the subtype_indication case, any ranges have to be corresponding; that is, two subtype_indications cannot conform unless both or neither has a range.

24.b
Discussion:  This definition is used in 9.5.2, "Entries and Accept Statements" for the conformance required between the discrete_subtype_definitions of an entry_declaration for a family of entries and the corresponding entry_index_specification of the entry_body.

Implementation Permissions

25
An implementation may declare an operator declared in a language-defined library unit to be intrinsic.

Extensions to Ada 83

25.a
The rules for full conformance are relaxed - they are now based on the structure of constructs, rather than the sequence of lexical elements. This implies, for example, that "(X, Y: T)" conforms fully with "(X: T; Y: T)", and "(X: T)" conforms fully with "(X: in T)".

6.3.2 Inline Expansion of Subprograms

1
[Subprograms may be expanded in line at the call site.]

Syntax

2
The form of a pragma Inline, which is a program unit pragma (see 10.1.5), is as follows:

3
pragma Inline(name {, name});

Legality Rules

4
The pragma shall apply to one or more callable entities or generic subprograms.

Static Semantics

5
If a pragma Inline applies to a callable entity, this indicates that inline expansion is desired for all calls to that entity. If a pragma Inline applies to a generic subprogram, this indicates that inline expansion is desired for all calls to all instances of that generic subprogram.

5.a
Ramification: Note that inline expansion is desired no matter what name is used in the call. This allows one to request inlining for only one of several overloaded subprograms as follows:

5.b
package IO is
   procedure Put(X : in Integer);
   procedure Put(X : in String);
   procedure Put(X : in Character);
private
   procedure Character_Put(X : in Character) renames Put;
   pragma Inline(Character_Put);
end IO;

5.c
with IO; use IO;
procedure Main is
   I : Integer;
   C : Character;
begin
   ...
   Put(C); --Inline expansion is desired.
   Put(I); --Inline expansion is NOT desired.
end Main;

5.d
Ramification: The meaning of a subprogram can be changed by a pragma Inline only in the presence of failing checks (see 11.6).

Implementation Permissions

6
For each call, an implementation is free to follow or to ignore the recommendation expressed by the pragma.

6.a
Ramification: Note, in particular, that the recommendation cannot always be followed for a recursive call, and is often infeasible for entries. Note also that the implementation can inline calls even when no such desire was expressed by a pragma, so long as the semantics of the program remains unchanged.

NOTES

7 6
The name in a pragma Inline can denote more than one entity in the case of overloading. Such a pragma applies to all of the denoted entities.

Extensions to Ada 83

7.a
A pragma Inline is allowed inside a subprogram_body if there is no corresponding subprogram_declaration. This is for uniformity with other program unit pragmas.



[Home] [Prev] [Next] [Index]

documentation@rational.com
Copyright © 1993-1998, Rational Software Corporation.   All rights reserved.