2016-11-15 53 views
5

Ada için yeni. Ada parametresi

Bu question gördüm, ama benim biraz farklıdır:

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; 

Sorum P2 olarak "out" parametresi ile: P2 açıkça olmasaydı kompozit türdeki diğer kısımları tanımsız edilecektir onları ayarla. Başka bir deyişle, eğer P1 çağrılırsa, çıktı kesinlikle doğru mu yoksa yanlış mı? Ya da belki belirsiz?

"Varsayılan başlatma" ile ilgili bu link görüşmeler, ama benim örnek yukarıda (bilerek) açıkça yoktur.

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. 

cevap

6

aktarılan bölüm, §6.1.1 Out Parameters, §6.2 Formal Parameter Modes inceledikten sonra anlamak daha kolay olabilir. tip A bir parametre için, "parametresi referans kopya ile veya ile verilirse bunun belirtilmemiştir." Uygulama seçmekte serbesttir. Her iki durumda da, A türünde bir değerin x bileşeni, P2 tarafından değiştirilmez. Açıkça önce P2 çağrılmasına x bileşenine 100 değerini verdik çünkü P1 baskılar "gerçek". Varsayılan olarak veya başka bir şekilde, temp.x yokluğunda başlatma, temp için tipik olarak bir yığın işaretçisi ayarlanarak, bellekte ne tür bitler olduğunu içerir.

bir alıştırma olarak, başlatma atlayarak ve değer inceleyerek deneyin: my uygulanması üzerinde

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

, yüklem başarısız olur ve temp.x çöp içermektedir. kayıt bileşenleri ile bir default_expression kullanma

false 
1934820168 200 

başlatma bakan riskini önler. o derleyici bağımlı ise

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

, o zaman çalıştığından emin olmak için in out tek emin yolu kullanıyor.

Yok varsayılan başlatma, evet. §6.1 Parameter and Result Mechanism belirtildiği gibi, "Ada 95'te bu parametre geçiş mekanizması bağlıdır erroneous değil (referans ile karşı yan kopya) o taşınmaz olsa, her ikisine de izin türlerinde." P2 yılında arg1kopya -ve bunun bir erişim tipi ne de Diskriminatları ile birleşik bir tür ne de §6.4.1 Parameter Associations biçimsel parametre olduğunu" açıkça ortaya koyuyor örtük başlangıç ​​değer-sahip bir tür ne olduğu ile geçirilebilir olabileceğini bir out parametre olduğu için başlatılmamış. " Buna karşılık, bir in out parametresi için, "asıl parametrenin değeri, formüle atanmış… ."

+1

Bunun derleyici özgü davranış olup olmadığından emin değilim? Kopyala geçebilen bir derleyici aynı davranır mı?Risk almaya çalışmam! –

+0

Teşekkür ederiz @trashgod. Derleyici bağımlıysa, o zaman çalıştığından emin olmak için "in out" (çıkış kaydedilen varsayılan başlatma var) emin değilseniz, "out out" kullanıyor: 'yordam P2 (arg1: out A) olduğunu 'begin' ' arg1.y: = 200; ' 'p P2;' –

+1

@TNguyen: Yukarıda ayrıntılandırdım. – trashgod