In and In Out parameters on a function call

20
Feb

If you've been programming for a while, you ran into variables passed by reference. This means the callee will be able to change the content of the caller's variables.

In general, such a call looks something like this:

1
2
3
4
my_var: integer
[...]
this_proc(my_var);
[...]

Assuming that this_proc() variable parameter is defined with in or in out, this means this_proc() can do my_var := <expression>; and that <expression> is what will be in my_var when the procedure returns.

However, in Ada, there is a subtle difference. The fact is that my_var is likely going to be set only if the function returns normally (opposed to returning because of an exception.) This is true for most variables. Special cases are any variable that cannot be copied (i.e. limited) and variables that represent an object with a discriminant because that could change the discriminant value which is obviously not a good idea.

So... what this means is that the caller is responsible for setting defaults in its variables, not the callee.

1
2
3
4
5
6
7
8
9
10
begin
  my_var := 5;
  this_proc(my_var);
exception
  when some_error =>
    if my_var /= 5 then
      -- this is not a valid Ada compiler
      raise program_error;
    end if;
end;

Note that there is one exception to this rule. If the procedure is ready to return and copying the results to the out variables fails with an exception (such as Constraint_Error,) then you may get some invalid results. However, that should not happen since such constraint should be caught before the procedure returns.

In pseudo code, a procedure call is equivalent to something like this:

1
2
3
4
5
6
7
8
9
10
11
12
declare
  type params is record
    param_my_var: integer;
  end record;
  p: params;
begin
  p.param_my_var := my_var;
  my_proc(p);
  my_var := p.param_my_var;
exception
  ...
end;

where the variable p is passed to my_proc() as a pointer to a read/write record.

As you can see, it is as if the result was taken care of in the caller, not the callee. Thus, if an exception occurs, the results are not saved back in the caller's variables. (In code, the copy could happen in the callee to save space since that way the callee does it once for all callers.)

Reference: 6.2 Formal Parameter Modes

Syndicate content