2016-11-15 28 views
5

Tôi mới tham gia Ada.Thông số Ada out

tôi thấy question này, nhưng tôi là một chút khác nhau:

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; 

Câu hỏi của tôi là với tham số "out" trong P2: sẽ các bộ phận khác của một loại composit được undefined nếu P2 không rõ ràng đặt chúng. Nói cách khác, nếu P1 được gọi, đầu ra có chắc chắn đúng hay sai? Hoặc có thể mơ hồ?

Điều này link nói về "khởi tạo mặc định", nhưng ví dụ trên của tôi không rõ ràng (có chủ đích).

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. 

Trả lời

6

Các đoạn trích dẫn, §6.1.1 Out Parameters, có thể dễ dàng hơn để hiểu sau khi xem xét §6.2 Formal Parameter Modes. Đối với tham số loại A, "không xác định xem thông số có được chuyển thành không bằng cách sao chép hoặc bằng cách tham chiếu". Việc thực hiện là miễn phí để lựa chọn. Trong cả hai trường hợp, thành phần x có giá trị loại A không thay đổi theo P2. P1 in "true" vì bạn đã cung cấp thành phần x giá trị 100 một cách rõ ràng trước khi gọi P2. Khởi tạo vắng mặt, mặc định hoặc cách khác, temp.x chứa bất kỳ bit nào trong bộ nhớ khi tạo chỗ cho temp, thường bằng cách điều chỉnh con trỏ ngăn xếp.

Là một tập thể dục, hãy thử bỏ qua việc khởi tạo và kiểm tra các giá trị:

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

Về việc thi hành của tôi, vị từ thất bại và temp.x chứa rác.

false 
1934820168 200 

Sử dụng default_expression với thành phần ghi để tránh rủi ro khi khởi tạo.

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

Nếu đó là biên dịch phụ thuộc, sau đó được sử dụng in out sự chắc chắn cách duy nhất để chắc chắn rằng nó hoạt động.

Khởi tạo mặc định vắng mặt, có. Như đã nêu trong §6.1 Parameter and Result Mechanism, "Trong Ada 95 nó không phải là erroneous phụ thuộc vào cơ chế truyền thông số (bởi tham chiếu so by-copy) đối với những loại mà cho phép cả hai, mặc dù nó là nonportable." Bởi vì arg1 trong P2 là một tham số out rằng thể được thông qua bằng cách sao chép -Và nó không phải là một loại truy cập hay một loại composite với biệt thức cũng không phải là loại có một tiềm ẩn ban đầu giá trị gia §6.4.1 Parameter Associations nói rõ rằng "tham số chính thức là uninitialized. " Ngược lại, đối với thông số in out, "giá trị của thông số thực tế là ... được chỉ định cho chính thức".

+1

Tôi không chắc liệu đây có phải là hành vi cụ thể của trình biên dịch không? Một trình biên dịch có thể vượt qua bằng cách sao chép hành xử giống nhau không?Tôi sẽ cố gắng không mạo hiểm nó! –

+0

Cảm ơn bạn @trashgod. Nếu nó là trình biên dịch phụ thuộc, sau đó sử dụng "in out" cách chắc chắn duy nhất để đảm bảo nó hoạt động (nếu bạn không chắc chắn bản ghi được truyền trong đã khởi tạo mặc định): 'procedure P2 (arg1: in out A) là ' ' bắt đầu' 'arg1.y: = 200;' 'kết thúc P2;' –

+1

@TNguyen: Tôi đã xây dựng ở trên. – trashgod