2016-11-15 9 views
5

私はAdaを使いました。Ada outパラメータ

私はこのquestionを見ましたが、私のは少し異なります。

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; 

私の質問はP2に「アウト」パラメータである:P2が明示的にしなかった場合は、複合タイプの他の部分は不定となりますそれらを設定します。言い換えれば、P1が呼び出された場合、出力は間違いなく真か偽でしょうか?それともあいまいですか?

このlinkは「デフォルトの初期化」について述べていますが、上記の例では明示的に(意図的に)設定していません。

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. 

答えて

6

引用された経路、§6.1.1 Out Parametersは、§6.2 Formal Parameter Modesを検討した後理解しやすいかもしれません。 Aタイプのパラメータについては、のパラメータがまたはで、に渡されるかどうかは不明です。実装は自由に選択できます。どちらの場合でも、タイプAxのコンポーネントはP2で変更されません。 P1P2を呼び出す前にコンポーネントに明示的に100という値を指定しているため、「true」を出力します。初期化されていない、デフォルトまたはそれ以外の場合、temp.xには、通常、スタックポインタを調整することによって、tempのためのスペースを確保するときにメモリにあったビットがすべて含まれます。

は練習として、初期化を省略し、値を調べてみてください。私の実装に

--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); 

は、述語は失敗し、temp.xはゴミが含まれています。

false 
1934820168 200 

default_expressionをレコードコンポーネントに使用すると、初期化が見落とされる危険性がなくなります。

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

それはコンパイラに依存している場合は、それが動作することを確認するためにin out唯一確実な方法を使用しています。

デフォルトの初期化がない、はい。 §6.1 Parameter and Result Mechanismに述べたように、「エイダ95ではそれは移植性あるが、両方の許可これらのタイプの(BY-コピー対によって参照)機構を渡すパラメータに依存するerroneousません。」 P2arg1コピーによってを渡すことができることをoutパラメータである - そしてそれは、アクセスタイプも判別式を持つ複合型でも暗黙の初期値 - §6.4.1 Parameter Associationsは、正式なパラメータであるクリア」ことになり有するタイプでもないので未初期化。 "対照的に、in outパラメータの場合、 "実際のパラメータの値は... が正式に割り当てられています。"

+1

コンパイラ固有の動作かどうかはわかりませんが、コピーを渡すことができたコンパイラは同じように動作しますか?私はそれを危険にさらさないようにしよう! –

+0

@trashgodありがとうございました。コンパイラに依存している場合は、 "in out"を使用して確実に動作することを確認します(渡されたレコードがデフォルトの初期化を持っているかどうかわからない場合): 'プロシージャP2(arg1:out A) ' ' begin' 'arg1.y:= 200;' 'end P2;' –

+1

@TNguyen:私は上記で詳述しました。 – trashgod