PARAMETER PASSING

1. INTRODUCTION

We have seem that procedures and functions may have formal parameters associated with them (parameters for functions and procedures). These formal parameters get instantiated with copies of the actual parameters when the procedure or function is called (routine invocation). So far we have assumed that parameters can only be passed to procedures/functions where they act as local constants (local to the procedure/function in question). If we want to return a value we must use a function. However, functions can only return a single value. Clearly there is a need to provide some mechanism whereby routines can return more than one value, or operate using actual parameters rather than copies. In fact most imperative programming languages (including Ada) also allow parameters to be passed back from procedures (other than through the use of a function call). Ada actually supports three different kinds of parameter:

  1. In parameters which are use to pass data items to procedures/functions
  2. Out parameters which are used to return data items from procedures
  3. In-out parameters which are used to pass data items to procedures, where they are updated and then returned.

By default Ada assumes that all parameters are "in" parameters. These are then the kind of parameters we have been using up to now. To ensure the correct operation of each of the above Ada uses the following general parameter passing mechanisms:

  1. Call by constant value
  2. Call by result
  3. Call by copy-restore (also know as call by value-result)

2. CALL BY CONSTANT VALUE

In "call by constant value" the formal parameter is instantiated with the value of an actual parameter passed to it from the calling procedure/function. This parameter then acts as a local constant within the called procedure/function. Example:

with TEXT_IO;
use TEXT_IO;

procedure IN_MODE_EXAMPLE is
    package FLOAT_INOUT is new FLOAT_IO(FLOAT);
    use FLOAT_INOUT;
    NUMBER_1, NUMBER_2: FLOAT;

    -----------------------------------------------------------------------------
    -- MEAN VALUE PROCEDURE
    procedure MEAN_VALUE(LOCAL_NUM_1, LOCAL_NUM_2: in FLOAT) is
    begin
        PUT("The mean is ");
        PUT((LOCAL_NUM_1+LOCAL_NUM_2)/2.0);
        NEW_LINE;
    end MEAN_VALUE;
    ----------------------------------------------------------------------------

-- TOP LEVEL PROCEDURE
begin
    PUT_LINE("Input two floating point numbers: ");
    GET(NUMBER_1);
    GET(NUMBER_2);
    MEAN_VALUE(NUMBER_1,NUMBER_2);
end IN_MODE_EXAMPLE;

Here the data items LOCAL_NUM_1 and LOCAL_NUM_2 act as constants for the procedure MEAN_VALUE. Note that, in Ada, we are not obliged to include the in reserved word when using "call by constant value".

The disadvantage of "call by constant value" is that a copy is always made of the actual parameter to obtain the formal parameter.


3. CALL BY RESULT

Call by result is used in Ada to implement out mode parameter passing. The formal parameter acts as an uninitialised local variable within the called procedure. The parameter is then assigned a value during execution. This value is then "passed back" and assigned to the actual ^ parameter on returning from the routine invocation (procedure call).

with TEXT_IO;
use TEXT_IO;

procedure OUT_MODE_EXAMPLE is
    package FLOAT_INOUT is new FLOAT_IO(FLOAT);
    use FLOAT_INOUT;
    NUMBER_1, NUMBER_2, MEAN: FLOAT;

    -----------------------------------------------------------------------------
    -- MEAN VALUE PROCEDURE
    procedure MEAN_VALUE(LOCAL_NUM_1, LOCAL_NUM_2: in FLOAT;
            LOCAL_MEAN: out FLOAT) is
    begin
        LOCAL_MEAN:= (LOCAL_NUM_1+LOCAL_NUM_2)/2.0;
    end MEAN_VALUE;
    ----------------------------------------------------------------------------

-- TOP LEVEL PROCEDURE
begin
    PUT_LINE("Input two floating point numbers: ");
    GET(NUMBER_1);
    GET(NUMBER_2);
    MEAN_VALUE(NUMBER_1,NUMBER_2,MEAN);
    PUT("The mean is ");
    PUT(MEAN);
    NEW_LINE;
end OUT_MODE_EXAMPLE;

Note: the Ada out parameter passing mechanism can only be used with procedures (not functions).


4. CALL BY COPY RESTORE

"Call by copy restore" (also known as "call by value result") is an amalgamation of "call by value" and "call by result". The formal parameter acts as a local variable which is initialised to the value of the actual parameter. Within the routine, changes to the formal parameter only effect the local copy. On returning from the routine the final value of the formal parameter is assigned to the actual parameter. Call by copy restore is supported by Ada to achieve "in-out" parameter operation. It has the same disadvantages as those associated with call by value.

with TEXT_IO;
use TEXT_IO;

procedure IN_OUT_MODE_EXAMPLE is
    package FLOAT_INOUT is new FLOAT_IO(FLOAT);
    use FLOAT_INOUT;
    NUMBER_1_AND_MEAN, NUMBER_2: FLOAT;

    -----------------------------------------------------------------------------
    -- MEAN VALUE PROCEDURE
    procedure MEAN_VALUE(LOCAL_NUM_1_AND_MEAN: in out FLOAT;
            LOCAL_NUM_2: in FLOAT) is
    begin
        LOCAL_NUM_1_AND_MEAN := (LOCAL_NUM_1_AND_MEAN+LOCAL_NUM_2)/2.0;
    end MEAN_VALUE;
    ----------------------------------------------------------------------------

-- TOP LEVEL PROCEDURE
begin
    PUT_LINE("Input two floating point numbers: ");
    GET(NUMBER_1_AND_MEAN);
    GET(NUMBER_2);
    MEAN_VALUE(NUMBER_1_AND_MEAN,NUMBER_2);
    PUT("The mean is ");
    PUT(NUMBER_1_AND_MEAN);
    NEW_LINE;
end IN_OUT_MODE_EXAMPLE;

Note: the in out parameter passing mechanism can only be used with respect to procedures.


5. POSITIONAL PARAMETER ASSOCIATION

In all the above examples we have used what is referred to as positional parameter association. When making a routine invocation the actual parameters (if any) are listed in the order in which we wish the association to occur. Thus, the first actual parameter is associated with the first formal parameter, the second actual parameter with the second formal parameter and so on. The term "positional parameter association" is used because the position of the actual parameter in a procedure call determines the formal parameter with which it is associated.


6. NAMED PARAMETER ASSOCIATION

Positional parameter association as described above is the most common approach to associating parameters with procedures/functions. The alternative is named parameter association. Consider the following:

with TEXT_IO;
use TEXT_IO;

procedure NAMED_PARAM_ASSOC is
    package FLOAT_INOUT is new FLOAT_IO(FLOAT);
    use FLOAT_INOUT;
    NUMBER_1, NUMBER_2, MEAN: FLOAT;

    -----------------------------------------------------------------------------
    -- MEAN VALUE PROCEDURE
    procedure MEAN_VALUE(LOCAL_NUM_1, LOCAL_NUM_2: in FLOAT;
            LOCAL_MEAN: out FLOAT) is
    begin
        LOCAL_MEAN:= (LOCAL_NUM_1+LOCAL_NUM_2)/2.0;
    end MEAN_VALUE;
    ----------------------------------------------------------------------------

-- TOP LEVEL PROCEDURE
begin
    PUT_LINE("Input two floating point numbers: ");
    GET(NUMBER_1);
    GET(NUMBER_2);
    MEAN_VALUE(LOCAL_NUM_1=>NUMBER_1, LOCAL_NUM_2=>NUMBER_2, LOCAL_MEAN=>MEAN);
    PUT("The mean is ");
    PUT(MEAN);
    NEW_LINE;
end NAMED_PARAM_ASSOC;

Here the term LOCAL_MUM_1=>NUMBER_1 means that the actual parameter NUMBER_1 should be associated with the formal parameterLOCAL_MUM_1. Similarly LOCAL_MUM_2=>NUMBER_2 means that the actual parameter NUMBER_2 should be associated with the formal parameterLOCAL_MUM_2, and so on. Note that named parameter association can be used with any of the Ada parameter passing modes. Note also that the order when using named parameter association is not significant. In the above example we could have equally well written:

MEAN_VALUE(LOCAL_NUM_2=>NUMBER_2, LOCAL_MEAN=>MEAN, LOCAL_NUM_1=>NUMBER_1);

Alternatively we could have used a mixture of named and positional parameter association provided that the positional associations are written first. For example in the above case we could have written:

MEAN_VALUE(NUMBER_1, LOCAL_MEAN=>MEAN, LOCAL_NUM_2=>NUMBER_2);

The latter is not advised as it can lead to confusion.


7. DEFAULT PARAMETERS

Consider the following program:

with TEXT_IO;
use TEXT_IO;

procedure DEFAULT_EXAMPLE is
    package FLOAT_INOUT is new FLOAT_IO(FLOAT);
    use FLOAT_INOUT;
    NUMBER_1, NUMBER_2: FLOAT;

    -----------------------------------------------------------------------------
    -- MEAN VALUE PROCEDURE
    procedure MEAN_VALUE(LOCAL_NUM_1: in FLOAT := 4.6; LOCAL_NUM_2: in FLOAT := 9.2) is
    begin
        PUT("The mean is ");
        PUT((LOCAL_NUM_1+LOCAL_NUM_2)/2.0,FORE=>2,AFT=>3,EXP=>0);
        NEW_LINE;
    end MEAN_VALUE;
    ----------------------------------------------------------------------------

-- TOP LEVEL PROCEDURE
begin
    MEAN_VALUE;
    PUT_LINE("Input two floating point numbers: ");
    GET(NUMBER_1);
    MEAN_VALUE(NUMBER_1);
    GET(NUMBER_2);
    MEAN_VALUE(LOCAL_NUM_2=>NUMBER_2);
    MEAN_VALUE(NUMBER_1,NUMBER_2);
end DEFAULT_EXAMPLE;

Here we have included default values for the formal parameters of the MEAN_VALUE procedure. In the absence of actual parameters these default parameters will be used whenever the procedure is called. However, the default parameters can be "over ridden" using actual parameters. Note that default parameters can only be used in the context of in mode parameters.




Created and maintained by Frans Coenen. Last updated 11 October 1999