我是艾达的新手。
我看到这个 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 中的“out”参数:如果 P2 没有明确设置复合类型的其他部分,它们是否会被未定义。换句话说,如果调用 P1,输出肯定是 true 还是 false?或者可能是模棱两可的?
此 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.1.1 Out Parameters , 回顾一下可能更容易理解§6.2 Formal Parameter Modes .对于 A
类型的参数, "未指定参数是通过副本传递还是通过引用传递。"实现方式可以自由选择。在任何一种情况下,x
A
类型值的组成部分P2
不变. P1
打印“true”,因为您给出了 x
分量值为 100
在调用 P2
之前明确.没有初始化,默认或其他,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;
If it is compiler dependent, then is using
in out
the only sure way to make sure it works.
没有默认初始化,是的。如 §6.1 Parameter and Result Mechanism 中所述,“在 Ada 95 中,对于那些允许两者的类型,依赖参数传递机制(按引用与按复制)不是 erroneous,尽管它是 不可移植 。”因为
arg1
在 P2
是 out
可以通过复制传递的参数——它既不是访问类型,也不是具有判别式的复合类型,也不是具有隐式初始值的类型——§6.4.1 Parameter Associations明确指出“形式参数是 未初始化 。”相比之下,对于 in out
参数,“实际参数的值是…… 分配给形式的 。”
关于parameters - Ada 输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40621326/