Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada out parameter

I'm new to Ada.

I saw this question, but mine is a little different:

    type A is record
        x : integer;
        y : integer;
    end record;

    procedure P1 is
      temp : A;
    begin
      temp.x := 100;
      P2(temp);
      if temp.x = 100 then
        Ada.Text_IO.Put_Line("true");
      else
        Ada.Text_IO.Put_Line("false");
      end if;
    end One;

    procedure P2 (arg1 : out A) is
    begin
      arg1.y := 200;
    end P2;

My question is with the "out" parameter in P2: will other parts of a composite type be undefined if P2 didn't explicitly set them. In other words, if P1 is called, would the output be definitely true or false? Or maybe ambiguous?

This link talks about "default initialization", but my example above doesn't have it explicitly (on purpose).

    Safety is preserved by ensuring that a subcomponent does not become
    "deinitialized" by being passed as an out parameter. If any subcomponent
    of a type passed by copy has default initialization, then the whole
    object is copied in at the start of the call so that the value of such a
    subcomponent is not lost as a result of a subprogram call during which
    no assignment is made to the subcomponent. But in practice records are
    usually passed by reference anyway.
like image 810
T Nguyen Avatar asked Nov 15 '16 23:11

T Nguyen


1 Answers

The quoted passage, §6.1.1 Out Parameters, may be easier to understand after reviewing §6.2 Formal Parameter Modes. For a parameter of type A, "it is unspecified whether the parameter is passed by copy or by reference." The implementation is free to choose. In either case, the x component of a value of type A is unchanged by P2. P1 prints "true" because you have given the x component a value of 100 explicitly prior to calling P2. Absent initialization, default or otherwise, temp.x contains whatever bits were in memory when making room for temp, typically by adjusting a stack pointer.

As an exercise, try omitting the initialization and examining the value:

--temp.x := 100;
P2(temp);
if temp.x = 100 then
   Ada.Text_IO.Put_Line("true");
else
   Ada.Text_IO.Put_Line("false");
end if;
Ada.Text_IO.Put_Line(temp.x'Img & temp.y'Img);

On my implementation, the predicate fails and temp.x contains garbage.

false
 1934820168 200

Using a default_expression with the record components avoids the risk of overlooking the initialization.

type A is record
    x : integer := 0;
    y : integer := 0;
end record;

If it is compiler dependent, then is using in out the only sure way to make sure it works.

Absent default initialization, yes. As noted in §6.1 Parameter and Result Mechanism, "In Ada 95 it is not erroneous to depend on the parameter passing mechanism (by-reference versus by-copy) for those types that allow both, though it is nonportable." Because arg1 in P2 is an out parameter that may be passed by copy—and it is neither an access type nor a composite type with discriminants nor a type having an implicit initial value—§6.4.1 Parameter Associations makes clear that "the formal parameter is uninitialized." In contrast, for an in out parameter, "the value of the actual parameter is…assigned to the formal."

like image 95
trashgod Avatar answered Oct 03 '22 04:10

trashgod