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.
For parameters of array and record types, the parameter passing rules have these consequences:
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, actual parameter, array type, assignment, bound of an array, constraint, depend on a discriminant, discriminant, entry call statement, erroneous, evaluation, exception, expression, formal parameter, generic formal parameter, global, mode, null access value, object, parameter specification, private type, record type, scalar type, subcomponent, subprogram body, subprogram call statement, task, task type, type mark, unconstrained array type, unconstrained type with discriminants, unconstrained variable, variable.
Rationale references: 8.2 Parameter Modes, 8.2.1 Efficiency Issues of Parameter Passing Mechanisms, 8.2.2 The Effect of Parameter Passing Mechanisms for Access Types, 8.2.3 The Effect of Parameter Passing Mechanisms for Composite Types, 8.2.4 The Ada Solution for Parameter Passing, 8.3 Parameter Passing Notations
Style Guide references: 2.1.5 More on Alignment, 5.2.4 Mode Indication, 5.9.3 Dependence on Parameter Passing Mechanism
Address any questions or comments to firstname.lastname@example.org.