2016-11-15 18 views
5

Jestem nowy dla Ady.Ada out parameter

Widziałem ten question, ale mój jest trochę inna:

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; 

Moje pytanie jest z parametrem „out” P2: będą inne części typu kompozytowego być niezdefiniowana jeśli nie jawnie P2 ustaw je. Innymi słowy, jeśli wywoływane jest P1, czy wynik byłby zdecydowanie prawdziwy czy fałszywy? A może niejednoznaczne?

Ta mówi o "domyślnej inicjalizacji", ale mój powyższy przykład nie ma tego wyraźnie (celowo).

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. 

Odpowiedz

6

Cytowany fragment, §6.1.1 Out Parameters mogą być łatwiejsze do zrozumienia po zapoznaniu §6.2 Formal Parameter Modes. W przypadku parametru typu A "nie jest określone, czy parametr został przekazany przez kopię lub przez odniesienie." Wdrożenie można dowolnie wybierać. W obu przypadkach komponent x o wartości typu A pozostaje niezmieniony przez P2. P1 drukuje "true", ponieważ podałeś 100 bezpośrednio przed wywołaniem P2. W przypadku braku inicjalizacji, domyślnej lub innej, temp.x zawiera wszystkie bity w pamięci, gdy robią miejsce dla temp, zwykle przez dostosowanie wskaźnika stosu.

Jako ćwiczenie, spróbuj pomijając inicjalizacji i badając wartość:

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

Na mojej realizacji, a orzeczenie nie zawiera temp.x śmieci.

false 
1934820168 200 

Korzystanie z default_expression z elementów płytowych eliminuje ryzyko przeoczenia inicjalizacji.

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

Jeśli jest to kompilator zależne, a następnie używa in out jedyny pewny sposób, aby upewnić się, że działa.

Brak domyślnej inicjalizacji, tak. Jak wskazano w §6.1 Parameter and Result Mechanism „W Ada 95 nie erroneous zależy od mechanizmu parametr mijania (przez odwołanie porównaniu przez imitowania) dla tych typów, które pozwalają zarówno, jeśli jest nieprzenośnej”. Ponieważ arg1 w P2 jest parametrem out że może być przekazywane przez kopię-i to nie jest ani typ dostępu ani kompozyt typu z wyróżników ani rodzajem posiadające niejawny początkową value- §6.4.1 Parameter Associations wyjaśnia, że”formalny parametr niezainicjowany. " Natomiast w przypadku parametru in out "wartość faktycznego parametru to ... przypisana do formalnej".

+1

Nie jestem pewien, czy jest to zachowanie specyficzne dla kompilatora? Czy kompilator, który mógłby przejść przez kopiowanie, zachowuje się tak samo?Staram się nie ryzykować! –

+0

Dziękuję @trashgod. Jeśli jest to zależne od kompilatora, to używa "out" jedynego pewny sposób, aby upewnić się, że działa (jeśli nie jesteś pewien, że przekazany rekord ma domyślną inicjalizację): 'procedura P2 (arg1: na wyjściu A) jest ' ' begin' 'arg1.y: = 200;' 'end P2;' –

+1

@TNguyen: Opracowałem powyżej. – trashgod