“out mode”和“in out mode”的主要区别是什么?

3

输出模式和双向输出模式之间的区别?根据我收集的信息,我知道的主要区别是,在输出模式和双向输出模式中,实际参数预计将被更改,甚至可以进行读写操作,那么主要区别是什么,请帮助我理解?


可能是Ada中IN OUT的使用的重复问题。 - Simon Wright
请不要将此关闭为重复项;有一些差异未在链接的问题中涵盖。我正在准备一个答案。 - ajb
1个回答

3
最好的差别解释在RM 6.4.1(11-15)中。
从语义上讲,只有通过复制传递的参数才有差异。如果你调用一个有in out参数的子程序,则在调用之前期望实际参数具有合法值。进入子程序后,会复制该变量,并检查它是否符合约束条件。
对于out参数,实际参数在输入时不需要有值;它可以是未初始化的垃圾。意图是子程序在设置该参数之前不使用此参数的值(它可以通过赋值或作为out参数传递给其他子程序、Default_Value或其他方式来设置)。但是,这并没有得到强制执行。
这可能在某些情况下导致不同的行为。例如:
subtype Int10 is Integer range 1 .. 10;

procedure Proc (Param : in out Int10) is 
begin
    Param := 5;
end Proc;

Y : Integer := 100;
...
Proc (Y);

由于Param是一个in out参数,因此在进入时会检查其约束条件。因此,对Proc(Y)的调用会引发Constraint_Error异常。但是:

subtype Int10 is Integer range 1 .. 10;

procedure Proc (Param : out Int10) is 
begin
    Param := 5;
end Proc;

Y : Integer := 100;
...
Proc (Y);

在这种情况下,不会引发Constraint_Error。事实上,Y根本不需要初始化,因为期望是过程不使用输入值。根据RM,对于某些参数类型的类,该值甚至没有被复制。因此,在这种情况下:
Save_Param : Integer;

procedure Proc (Param : out Int10) is 
begin
    Save_Param := Param;  -- legal but not recommended
    Param := 5;
end Proc;

Y : Integer := 3;
...
Proc (Y);
Save_Param 可能会被设置为一些垃圾值,而不是 3。(在 Ada 2012 中,有一个Default_Value aspect可应用于子类型;在这种情况下,out 参数将被设为此默认值,而不是未初始化的垃圾值,而in out参数仍会从实际参数中获得值。)
对于按引用传递的参数,实际上没有任何行为差异。
Ada 83 的规则是不同的。带有in out参数的子程序既可以读取又可以写入该参数,而带有out参数的子程序只允许分配给该参数,但不能执行任何读取该参数值的操作(除非存在无法避免读取判别因子的情况)。因此:
procedure Proc (Param : out Int10) is 
begin
    Param := 5;
    Save_Param := Param;  -- illegal in Ada 83, legal in Ada 95 and later versions
end Proc;

换句话说,一个out参数实际上只是输出。然而,在Ada 95中放宽了这个规则,因为程序员发现它太严格了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接