[comp.lang.ada] Parameter Passing and Exceptions

mfeldman@seas.gwu.edu (Michael Feldman) (05/01/91)

Sorry about the length of this posting, but I thought it would be best to
let the LRM speak for itself instead of paraphrasing it. It's all here.
Really. By the way: the LRM is available in machine-readable (ASCII) form
on both Simtel20 and AJPO machines.

Mike Feldman

------ cut here ------

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