The Ada Joint Program Office does not guarantee the accuracy of this file, as compared with the contents of ANSI/MIL-STD-1815A-1983, the Reference Manual for the Ada Programming Language. If errors or discrepancies are found in this machine-readable version, please forward comments via the Defense Data Network (DDN) to: ACTION@AJPO.SEI.CMU.EDU or via conventional mail to Ada Information Clearinghouse 3D139 (1211 S. Fern, C-107) The Pentagon Washington, D.C. 20301-3081 ----------------------------------------------------------------------- Copyright 1980, 1982, 1983 owned by the United States Government as represented by the Under Secretary of Defense, Research and Engineering. All rights reserved. Provided that notice of copyright is included on the first page, this document may be copied in its entirety without alteration or as altered by (1) adding text that is clearly marked as an insertion; (2) shading or highlighting existing text; (3) deleting examples. Permission to publish other excerpts should be obtained from the Ada Joint Program Office, OUSDRE (R&AT), The Pentagon, Washington, DC 20301-2081, U.S.A. 6. Subprograms Subprograms are one of the four forms of program unit, of which programs can be composed. The other forms are packages, task units, and generic units. A subprogram is a program unit whose execution is invoked by a subprogram call. There are two forms of subprogram: procedures and functions. A procedure call is a statement; a function call is an expression and returns a value. The definition of a subprogram can be given in two parts: a subprogram declaration defining its calling conventions, and a subprogram body defining its execution. References: function 6.5, function call 6.4, generic unit 12, package 7, procedure 6.1, procedure call 6.4, subprogram body 6.3, subprogram call 6.4, subprogram declaration 6.1, task unit 9 6.1 Subprogram Declarations A subprogram declaration declares a procedure or a function, as indicated by the initial reserved word. subprogram_declaration ::= subprogram_specification; subprogram_specification ::= procedure identifier [formal_part] | function designator [formal_part] return type_mark designator ::= identifier | operator_symbol operator_symbol ::= string_literal formal_part ::= (parameter_specification {; parameter_specification}) parameter_specification ::= identifier_list : mode type_mark [:= expression] mode ::= [in] | in out | out The specification of a procedure specifies its identifier and its formal parameters (if any). The specification of a function specifies its designator, its formal parameters (if any) and the subtype of the returned value (the result subtype). A designator that is an operator symbol is used for the overloading of an operator. The sequence of characters represented by an operator symbol must be an operator belonging to one of the six classes of overloadable operators defined in section 4.5 (extra spaces are not allowed and the case of letters is not significant). A parameter specification with several identifiers is equivalent to a sequence of single parameter specifications, as explained in section 3.2. Each single parameter specification declares a formal parameter. If no mode is explicitly given, the mode in is assumed. If a parameter specification ends with an expression, the expression is the default expression of the formal parameter. A default expression is only allowed in a parameter specification if the mode is in (whether this mode is indicated explicitly or implicitly). The type of a default expression must be that of the corresponding formal parameter. The use of a name that denotes a formal parameter is not allowed in default expressions of a formal part if the specification of the parameter is itself given in this formal part. The elaboration of a subprogram declaration elaborates the corresponding formal part. The elaboration of a formal part has no other effect. Examples of subprogram declarations: procedure TRAVERSE_TREE; procedure INCREMENT(X : in out INTEGER); procedure RIGHT_INDENT(MARGIN : out LINE_SIZE); -- see 3.5.4 procedure SWITCH(FROM, TO : in out LINK); -- see 3.8.1 function RANDOM return PROBABILITY; -- see 3.5.7 function MIN_CELL(X : LINK) return CELL; -- see 3.8.1 function NEXT_FRAME(K : POSITIVE) return FRAME; -- see 3.8 function DOT_PRODUCT(LEFT,RIGHT: VECTOR) return REAL; -- see 3.6 function "*"(LEFT,RIGHT : MATRIX) return MATRIX; -- see 3.6 Examples of in parameters with default expressions: procedure PRINT_HEADER(PAGES : in NATURAL; HEADER : in LINE := (1 .. LINE'LAST => ' '); -- see 3.6 CENTER : in BOOLEAN := TRUE); Notes: The evaluation of default expressions is caused by certain subprogram calls, as described in section 6.4.2 (default expressions are not evaluated during the elaboration of the subprogram declaration). All subprograms can be called recursively and are reentrant. References: declaration 3.1, elaboration 3.9, evaluation 4.5, expression 4.4, formal parameter 6.2, function 6.5, identifier 2.3, identifier list 3.2, mode 6.2, name 4.1, elaboration has no other effect 3.9, operator 4.5, overloading 6.6 8.7, procedure 6, string literal 2.6, subprogram call 6.4, type mark 3.3.2 6.2 Formal Parameter Modes The value of an object is said to be read when this value is evaluated; it is also said to be read when one of its subcomponents is read. The value of a variable is said to be updated when an assignment is performed to the variable, and also (indirectly) when the variable is used as actual parameter of a subprogram call or entry call statement that updates its value; it is also said to be updated when one of its subcomponents is updated. A formal parameter of a subprogram has one of the three following modes: in The formal parameter is a constant and permits only reading of the value of the associated actual parameter. in out The formal parameter is a variable and permits both reading and updating of the value of the associated actual parameter. out The formal parameter is a variable and permits updating of the value of the associated actual parameter. The value of a scalar parameter that is not updated by the call is undefined upon return; the same holds for the value of a scalar subcomponent, other than a discriminant. Reading the bounds and discriminants of the formal parameter and of its subcomponents is allowed, but no other reading. For a scalar parameter, the above effects are achieved by copy: at the start of each call, if the mode is in or in out, the value of the actual parameter is copied into the associated formal parameter; then after normal completion of the subprogram body, if the mode is in out or out, the value of the formal parameter is copied back into the associated actual parameter. For a parameter whose type is an access type, copy-in is used for all three modes, and copy-back for the modes in out and out. For a parameter whose type is an array, record, or task type, an implementation may likewise achieve the above effects by copy, as for scalar types. In addition, if copy is used for a parameter of mode out, then copy-in is required at least for the bounds and discriminants of the actual parameter and of its subcomponents, and also for each subcomponent whose type is an access type. Alternatively, an implementation may achieve these effects by reference, that is, by arranging that every use of the formal parameter (to read or to update its value) be treated as a use of the associated actual parameter, throughout the execution of the subprogram call. The language does not define which of these two mechanisms is to be adopted for parameter passing, nor whether different calls to the same subprogram are to use the same mechanism. The execution of a program is erroneous if its effect depends on which mechanism is selected by the implementation. For a parameter whose type is a private type, the above effects are achieved according to the rule that applies to the corresponding full type declaration. Within the body of a subprogram, a formal parameter is subject to any constraint resulting from the type mark given in its parameter specification. For a formal parameter of an unconstrained array type, the bounds are obtained from the actual parameter, and the formal parameter is constrained by these bounds (see 3.6.1). For a formal parameter whose declaration specifies an unconstrained (private or record) type with discriminants, the discriminants of the formal parameter are initialized with the values of the corresponding discriminants of the actual parameter; the formal parameter is unconstrained if and only if the mode is in out or out and the variable name given for the actual parameter denotes an unconstrained variable (see 3.7.1 and 6.4.1). If the actual parameter of a subprogram call is a subcomponent that depends on discriminants of an unconstrained record variable, then the execution of the call is erroneous if the value of any of the discriminants of the variable is changed by this execution; this rule does not apply if the mode is in and the type of the subcomponent is a scalar type or an access type. Notes: For parameters of array and record types, the parameter passing rules have these consequences: - If the execution of a subprogram is abandoned as a result of an exception, the final value of an actual parameter of such a type can be either its value before the call or a value assigned to the formal parameter during the execution of the subprogram. - If no actual parameter of such a type is accessible by more than one path, then the effect of a subprogram call (unless abandoned) is the same whether or not the implementation uses copying for parameter passing. If, however, there are multiple access paths to such a parameter (for example, if a global variable, or another formal parameter, refers to the same actual parameter), then the value of the formal is undefined after updating the actual other than by updating the formal. A program using such an undefined value is erroneous. The same parameter modes are defined for formal parameters of entries (see 9.5) with the same meaning as for subprograms. Different parameter modes are defined for generic formal parameters (see 12.1.1). For all modes, if an actual parameter designates a task, the associated formal parameter designates the same task; the same holds for a subcomponent of an actual parameter and the corresponding subcomponent of the associated formal parameter. References: access type 3.8, actual parameter 6.4.1, array type 3.6, assignment 5.2, bound of an array 3.6.1, constraint 3.3, depend on a discriminant 3.7.1, discriminant 3.7.1, entry call statement 9.5, erroneous 1.6, evaluation 4.5, exception 11, expression 4.4, formal parameter 6.1, generic formal parameter 12.1, global 8.1, mode 6.1, null access value 3.8, object 3.2, parameter specification 6.1, private type 7.4, record type 3.7, scalar type 3.5, subcomponent 3.3, subprogram body 6.3, subprogram call statement 6.4, task 9, task type 9.2, type mark 3.3.2, unconstrained array type 3.6, unconstrained type with discriminants 3.7.1, unconstrained variable 3.2.1, variable 3.2.1 6.3 Subprogram Bodies A subprogram body specifies the execution of a subprogram. subprogram_body ::= subprogram_specification is [declarative_part] begin sequence_of_statements [exception exception_handler {exception_handler}] end [designator]; The declaration of a subprogram is optional. In the absence of such a declaration, the subprogram specification of the subprogram body (or body stub) acts as the declaration. For each subprogram declaration, there must be a corresponding body (except for a subprogram written in another language, as explained in section 13.9). If both a declaration and a body are given, the subprogram specification of the body must conform to the subprogram specification of the declaration (see section 6.3.1 for conformance rules). If a designator appears at the end of a subprogram body, it must repeat the designator of the subprogram specification. The elaboration of a subprogram body has no other effect than to establish that the body can from then on be used for the execution of calls of the subprogram. The execution of a subprogram body is invoked by a subprogram call (see 6.4). For this execution, after establishing the association between formal parameters and actual parameters, the declarative part of the body is elaborated, and the sequence of statements of the body is then executed. Upon completion of the body, return is made to the caller (and any necessary copying back of formal to actual parameters occurs (see 6.2)). The optional exception handlers at the end of a subprogram body handle exceptions raised during the execution of the sequence of statements of the subprogram body (see 11.4). Note: It follows from the visibility rules that if a subprogram declared in a package is to be visible outside the package, a subprogram specification must be given in the visible part of the package. The same rules dictate that a subprogram declaration must be given if a call of the subprogram occurs textually before the subprogram body (the declaration must then occur earlier than the call in the program text). The rules given in sections 3.9 and 7.1 imply that a subprogram declaration and the corresponding body must both occur immediately within the same declarative region. Example of subprogram body: 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; References: actual parameter 6.4.1, body stub 10.2, conform 6.3.1, declaration 3.1, declarative part 3.9, declarative region 8.1, designator 6.1, elaboration 3.9, elaboration has no other effect 3.1, exception 11, exception handler 11.2, formal parameter 6.1, occur immediately within 8.1, package 7, sequence of statements 5.1, subprogram 6, subprogram call 6.4, subprogram declaration 6.1, subprogram specification 6.1, visibility 8.3, visible part 7.2 6.3.1 Conformance Rules Whenever the language rules require or allow the specification of a given subprogram to be provided in more than one place, the following variations are allowed at each place: - A numeric literal can be replaced by a different numeric literal if and only if both have the same value. - A simple name can be replaced by an expanded name in which this simple name is the selector, if and only if at both places the meaning of the simple name is given by the same declaration. - A string literal given as an operator symbol can be replaced by a different string literal if and only if both represent the same operator. Two subprogram specifications are said to conform if, apart from comments and the above allowed variations, both specifications are formed by the same sequence of lexical elements, and corresponding lexical elements are given the same meaning by the visibility and overloading rules. Conformance is likewise defined for formal parts, discriminant parts, and type marks (for deferred constants and for actual parameters that have the form of a type conversion (see 6.4.1)). Notes: A simple name can be replaced by an expanded name even if the simple name is itself the prefix of a selected component. For example, Q.R can be replaced by P.Q.R if Q is declared immediately within P. The following specifications do not conform since they are not formed by the same sequence of lexical elements: procedure P(X,Y : INTEGER) procedure P(X : INTEGER; Y : INTEGER) procedure P(X,Y : in INTEGER) References: actual parameter 6.4 6.4.1, allow 1.6, comment 2.7, declaration 3.1, deferred constant 7.4.3, direct visibility 8.3, discriminant part 3.7.1, expanded name 4.1.3, formal part 6.1, lexical element 2, name 4.1, numeric literal 2.4, operator symbol 6.1, overloading 6.6 8.7, prefix 4.1, selected component 4.1.3, selector 4.1.3, simple name 4.1, subprogram specification 6.1, type conversion 4.6, visibility 8.3 6.3.2 Inline Expansion of Subprograms The pragma INLINE is used to indicate that inline expansion of the subprogram body is desired for every call of each of the named subprograms. The form of this pragma is as follows: pragma INLINE (name {, name}); Each name is either the name of a subprogram or the name of a generic subprogram. The pragma INLINE is only allowed at the place of a declarative item in a declarative part or package specification, or after a library unit in a compilation, but before any subsequent compilation unit. If the pragma appears at the place of a declarative item, each name must denote a subprogram or a generic subprogram declared by an earlier declarative item of the same declarative part or package specification. If several (overloaded) subprograms satisfy this requirement, the pragma applies to all of them. If the pragma appears after a given library unit, the only name allowed is the name of this unit. If the name of a generic subprogram is mentioned in the pragma, this indicates that inline expansion is desired for calls of all subprograms obtained by instantiation of the named generic unit. The meaning of a subprogram is not changed by the pragma INLINE. For each call of the named subprograms, an implementation is free to follow or to ignore the recommendation expressed by the pragma. (Note, in particular, that the recommendation cannot generally be followed for a recursive subprogram.) References: allow 1.6, compilation 10.1, compilation unit 10.1, declarative item 3.9, declarative part 3.9, generic subprogram 12.1, generic unit 12 12.1, instantiation 12.3, library unit 10.1, name 4.1, overloading 6.6 8.7, package specification 7.1, pragma 2.8, subprogram 6, subprogram body 6.3, subprogram call 6.4 6.4 Subprogram Calls A subprogram call is either a procedure call statement or a function call; it invokes the execution of the corresponding subprogram body. The call specifies the association of the actual parameters, if any, with formal parameters of the subprogram. procedure_call_statement ::= procedure_name [actual_parameter_part]; function_call ::= function_name [actual_parameter_part] actual_parameter_part ::= (parameter_association {, parameter_association}) parameter_association ::= [formal_parameter =>] actual_parameter formal_parameter ::= parameter_simple_name actual_parameter ::= expression | variable_name | type_mark(variable_name) Each parameter association associates an actual parameter with a corresponding formal parameter. A parameter association is said to be named if the formal parameter is named explicitly; it is otherwise said to be positional. For a positional association, the actual parameter corresponds to the formal parameter with the same position in the formal part. Named associations can be given in any order, but if both positional and named associations are used in the same call, positional associations must occur first, at their normal position. Hence once a named association is used, the rest of the call must use only named associations. For each formal parameter of a subprogram, a subprogram call must specify exactly one corresponding actual parameter. This actual parameter is specified either explicitly, by a parameter association, or, in the absence of such an association, by a default expression (see 6.4.2). The parameter associations of a subprogram call are evaluated in some order that is not defined by the language. Similarly, the language rules do not define in which order the values of in out or out parameters are copied back into the corresponding actual parameters (when this is done). Examples of procedure calls: TRAVERSE_TREE; -- see 6.1 TABLE_MANAGER.INSERT(E); -- see 7.5 PRINT_HEADER(128, TITLE, TRUE); -- see 6.1 SWITCH(FROM => X, TO => NEXT); -- see 6.1 PRINT_HEADER(128, HEADER => TITLE, CENTER => TRUE -- see 6.1 PRINT_HEADER(HEADER => TITLE, CENTER => TRUE, PAGES => 128); -- see 6.1 Examples of function calls: DOT_PRODUCT(U, V) -- see 6.1 and 6.5 CLOCK -- see 9.6 References: default expression for a formal parameter 6.1, erroneous 1.6, expression 4.4, formal parameter 6.1, formal part 6.1, name 4.1, simple name 4.1, subprogram 6, type mark 3.3.2, variable 3.2.1 6.4.1 Parameter Associations Each actual parameter must have the same type as the corresponding formal parameter. An actual parameter associated with a formal parameter of mode in must be an expression; it is evaluated before the call. An actual parameter associated with a formal parameter of mode in out or out must be either the name of a variable, or of the form of a type conversion whose argument is the name of a variable. In either case, for the mode in out, the variable must not be a formal parameter of mode out or a subcomponent thereof. For an actual parameter that has the form of a type conversion, the type mark must conform (see 6.3.1) to the type mark of he formal parameter; the allowed operand and target types are the same as for type conversions (see 4.6). The variable name given for an actual parameter of mode in out or out is evaluated before the call. If the actual parameter has the form of a type conversion, then before the call, for a parameter of mode in out, the variable is converted to the specified type; after (normal) completion of the subprogram body, for a parameter of mode in out or out, the formal parameter is converted back to the type of the variable. (The type specified in the conversion must be that of the formal parameter.) The following constraint checks are performed for parameters of scalar and access types: - Before the call: for a parameter of mode in or in out, it is checked that the value of the actual parameter belongs to the subtype of the formal parameter. - After (normal) completion of the subprogram body: for a parameter of mode in out or out, it is checked that the value of the formal parameter belongs to the subtype of the actual variable. In the case of a type conversion, the value of the formal parameter is converted back and the check applies to the result of the conversion. In each of the above cases, the execution of the program is erroneous if the checked value is undefined. For other types, for all modes, a check is made before the call as for scalar and access types; no check is made upon return. The exception CONSTRAINT_ERROR is raised at the place of the subprogram call if either of these checks fails. Note: For array types and for types with discriminants, the check before the call is sufficient (a check upon return would be redundant) if the type mark of the formal parameter denotes a constrained subtype, since neither array bounds nor discriminants can then vary. If this type mark denotes an unconstrained array type, the formal parameter is constrained with the bounds of the corresponding actual parameter and no check (neither before the call nor upon return) is needed (see 3.6.1). Similarly, no check is needed if the type mark denotes an unconstrained type with discriminants, since the formal parameter is then constrained exactly as the corresponding actual parameter (see 3.7.1). References: actual parameter 6.4, array bound 3.6, array type 3.6, call of a subprogram 6.4, conform 6.3.1, constrained subtype 3.3, constraint 3.3, constraint_error exception 11.1, discriminant 3.7.1, erroneous 1.6, evaluation 4.5, evaluation of a name 4.1, expression 4.4, formal parameter 6.1, mode 6.1, name 4.1, parameter association 6.4, subtype 3.3, type 3.3, type conversion 4.6, type mark 3.3.2, unconstrained array type 3.6, unconstrained type with discriminants 3.7.1, undefined value 3.2.1, variable 3.2.1 6.4.2 Default Parameters If a parameter specification includes a default expression for a parameter of mode in, then corresponding subprogram calls need not include a parameter association for the parameter. If a parameter association is thus omitted from a call, then the rest of the call, following any initial positional associations, must use only named associations. For any omitted parameter association, the default expression is evaluated before the call and the resulting value is used as an implicit actual parameter. Examples of procedures with default values: procedure ACTIVATE(PROCESS : in PROCESS_NAME; AFTER : in PROCESS_NAME := NO_PROCESS; WAIT : in DURATION := 0.0; PRIOR : in BOOLEAN := FALSE); procedure PAIR(LEFT, RIGHT : PERSON_NAME := new PERSON); Examples of their calls: ACTIVATE(X); ACTIVATE(X, AFTER => Y); ACTIVATE(X, WAIT => 60.0, PRIOR => TRUE); ACTIVATE(X, Y, 10.0, FALSE); PAIR; PAIR(LEFT => new PERSON, RIGHT => new PERSON); Note: If a default expression is used for two or more parameters in a multiple parameter specification, the default expression is evaluated once for each omitted parameter. Hence in the above examples, the two calls of PAIR are equivalent. References: actual parameter 6.4.1, default expression for a formal parameter 6.1, evaluation 4.5, formal parameter 6.1, mode 6.1, named parameter association 6.4, parameter association 6.4, parameter specification 6.1, positional parameter association 6.4, subprogram call 6.4 6.5 Function Subprograms A function is a subprogram that returns a value (the result of the function call). The specification of a function starts with the reserved word function, and the parameters, if any, must have the mode in (whether this mode is specified explicitly or implicitly). The statements of the function body (excluding statements of program units that are inner to the function body) must include one or more return statements specifying the returned value. The exception PROGRAM_ERROR is raised if a function body is left otherwise than by a return statement. This does not apply if the execution of the function is abandoned as a result of an exception. Example: 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; References: exception 11, formal parameter 6.1, function 6.1, function body 6.3, function call 6.4, function specification 6.1, mode 6.1, program_error exception 11.1, raising of exceptions 11, return statement 5.8, statement 5 6.6 Parameter and Result Type Profile - Overloading of Subprograms Two formal parts are said to have the same parameter type profile if and only if they have the same number of parameters, and at each parameter position corresponding parameters have the same base type. A subprogram or entry has the same parameter and result type profile as another subprogram or entry if and only if both have the same parameter type profile, and either both are functions with the same result base type, or neither of the two is a function. The same subprogram identifier or operator symbol can be used in several subprogram specifications. The identifier or operator symbol is then said to be overloaded; the subprograms that have this identifier or operator symbol are also said to be overloaded and to overload each other. As explained in section 8.3, if two subprograms overload each other, one of them can hide the other only if both subprograms have the same parameter and result type profile (see section 8.3 for the other requirements that must be met for hiding). A call to an overloaded subprogram is ambiguous (and therefore illegal) if the name of the subprogram, the number of parameter associations, the types and the order of the actual parameters, the names of the formal parameters (if named associations are used), and the result type (for functions) are not sufficient to determine exactly one (overloaded) subprogram specification. Examples of overloaded subprograms: procedure PUT(X : INTEGER); procedure PUT(X : STRING); procedure SET(TINT : COLOR); procedure SET(SIGNAL : LIGHT); Examples of calls: PUT(28); PUT("no possible ambiguity here"); SET(TINT => RED); SET(SIGNAL => RED); SET(COLOR'(RED)); -- SET(RED) would be ambiguous since RED may -- denote a value either of type COLOR or of type LIGHT Notes: The notion of parameter and result type profile does not include parameter names, parameter modes, parameter subtypes, default expressions and their presence or absence. Ambiguities may (but need not) arise when actual parameters of the call of an overloaded subprogram are themselves overloaded function calls, literals, or aggregates. Ambiguities may also (but need not) arise when several overloaded subprograms belonging to different packages are visible. These ambiguities can usually be resolved in several ways: qualified expressions can be used for some or all actual parameters, and for the result, if any; the name of the subprogram can be expressed more explicitly as an expanded name; finally, the subprogram can be renamed. References: actual parameter 6.4.1, aggregate 4.3, base type 3.3, default expression for a formal parameter 6.1, entry 9.5, formal parameter 6.1, function 6.5, function call 6.4, hiding 8.3, identifier 2.3, illegal 1.6, literal 4.2, mode 6.1, named parameter association 6.4, operator symbol 6.1, overloading 8.7, package 7, parameter of a subprogram 6.2, qualified expression 4.7, renaming declaration 8.5, result subtype 6.1, subprogram 6, subprogram specification 6.1, subtype 3.3, type 3.3 6.7 Overloading of Operators The declaration of a function whose designator is an operator symbol is used to overload an operator. The sequence of characters of the operator symbol must be either a logical, a relational, a binary adding, a unary adding, a multiplying, or a highest precedence operator (see 4.5). Neither membership tests nor the short-circuit control forms are allowed as function designators. The subprogram specification of a unary operator must have a single parameter. The subprogram specification of a binary operator must have two parameters; for each use of this operator, the first parameter takes the left operand as actual parameter, the second parameter takes the right operand. Similarly, a generic function instantiation whose designator is an operator symbol is only allowed if the specification of the generic function has the corresponding number of parameters. Default expressions are not allowed for the parameters of an operator (whether the operator is declared with an explicit subprogram specification or by a generic instantiation). For each of the operators "+" and "-", overloading is allowed both as a unary and as a binary operator. The explicit declaration of a function that overloads the equality operator "=", other than by a renaming declaration, is only allowed if both parameters are of the same limited type. An overloading of equality must deliver a result of the predefined type BOOLEAN; it also implicitly overloads the inequality operator "/=" so that this still gives the complementary result to the equality operator. Explicit overloading of the inequality operator is not allowed. A renaming declaration whose designator is the equality operator is only allowed to rename another equality operator. (For example, such a renaming declaration can be used when equality is visible by selection but not directly visible.) Note: Overloading of relational operators does not affect basic comparisons such as testing for membership in a range or the choices in a case statement. Examples: function "+" (LEFT, RIGHT : MATRIX) return MATRIX; function "+" (LEFT, RIGHT : VECTOR) return VECTOR; -- assuming that A, B, and C are of the type VECTOR -- the three following assignments are equivalent A := B + C; A := "+"(B, C); A := "+"(LEFT => B, RIGHT => C); References: allow 1.6, actual parameter 6.4.1, binary adding operator 4.5 4.5.3, boolean predefined type 3.5.3, character 2.1, complementary result 4.5.2, declaration 3.1, default expression for a formal parameter 6.1, designator 6.1, directly visible 8.3, equality operator 4.5, formal parameter 6.1, function declaration 6.1, highest precedence operator 4.5 4.5.6, implicit declaration 3.1, inequality operator 4.5.2, limited type 7.4.4, logical operator 4.5 4.5.1, membership test 4.5 4.5.2, multiplying operator 4.5 4.5.5, operator 4.5, operator symbol 6.1, overloading 6.6 8.7, relational operator 4.5 4.5.2, short-circuit control form 4.5 4.5.1, type definition 3.3.1, unary adding operator 4.5 4.5.4, visible by selection 8.3