Ada 函数参数是否作为访问类型
Ada Function Parameter as Access Type or Not
我正在重构一些最初使用访问类型编写但尚未测试的代码。我发现 Ada 中的访问类型很麻烦,因为它们只能引用动态分配的项,而引用在编译时定义的项显然是不允许的。 (这是 Ada83。)
但现在我遇到了这样一个函数:
function Get_Next(stateInfo : State_Info_Access_Type) return integer;
我知道我可以轻松传递访问类型的参数 "contents" 而不是访问指针本身,所以我正在考虑将其写为
function Get_Next(stateInfoPtr : State_Info_Type) return integer;
其中 State_Info_Type 是 State_Info_Access_Type 所指的类型。
通过这次重构,出于所有意图和目的,我认为我仍然真正将相当于隐式指针的内容传递回内容(使用 .all) 语法) .
我想从最低级别的函数开始重构和测试,然后逐步向上调用链。我的目标是在进行时将访问类型推出代码。
我理解正确还是我遗漏了什么?
引用@T.E.D,
Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine.
由于这段代码还没有经过测试,我认为你重新编写看起来像用 C 思维编写的代码是完全正确的。但是,您根本不应该提及指针;你建议
function Get_Next(stateInfoPtr : State_Info_Type) return integer;
但这样会更好
function Get_Next(stateInfo : State_Info_Type) return integer;
甚至(IMO)为
function Get_Next(State_Info : State_Info_Type) return Integer;
使用更标准的 Ada 样式!我的编辑器(Emacs,但 GPS 也可以这样做)会即时将 state_info
更改为 State_Info
。
作为事后的想法,您可以完全摆脱 State_Info_Type_Pointer
。你提到 .all
,所以我猜你有
SITP : State_Info_Type_Pointer := new State_Info_Type;
... set up components
Next := Get_Next (SITP.all);
但是
SIT : State_Info_Type;
... set up components
Next := Get_Next (SIT);
我认为原作者,可能还有 OP 遗漏了一点,即 Ada 参数模式的工作原理。
引用@T.E.D
Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine.
Ada 会自动执行此操作,并将参数模式作为描述信息流的一种方式(这不是 C 样式引用/值难题)。看到有用的wikibook.
让我担心的是,您继承的代码看起来像作者使用显式 access
参数类型作为使函数产生副作用的一种方式(在 Ada 中通常被认为是一件坏事 - World ).
我的建议是将您的函数更改为:
function Get_Next(State_Info : in State_Info_Type) return Integer;
看看编译器是否告诉您您是否正在尝试修改 State_Info
。如果是这样,您可能需要将函数更改为这样的过程:
procedure Get_Next(State_Info : in out State_Info_Type;
Result : out Integer);
这显式显示了信息流,无需知道寄存器大小或 State_Info_Type
的大小。
顺便说一句,Ada 2012 将允许您拥有具有 in out
个参数的函数。
我不推荐这样做,但您可以使用“地址”获取指向 Ada 83 中变量的指针。
然后您可以使用覆盖(同样这都是 Ada83 的东西)来实现访问...
function something(int_address : Address) return integer
is
x : integer;
for x'address use int_address;
begin
-- play with x as you will.
我正在重构一些最初使用访问类型编写但尚未测试的代码。我发现 Ada 中的访问类型很麻烦,因为它们只能引用动态分配的项,而引用在编译时定义的项显然是不允许的。 (这是 Ada83。)
但现在我遇到了这样一个函数:
function Get_Next(stateInfo : State_Info_Access_Type) return integer;
我知道我可以轻松传递访问类型的参数 "contents" 而不是访问指针本身,所以我正在考虑将其写为
function Get_Next(stateInfoPtr : State_Info_Type) return integer;
其中 State_Info_Type 是 State_Info_Access_Type 所指的类型。
通过这次重构,出于所有意图和目的,我认为我仍然真正将相当于隐式指针的内容传递回内容(使用 .all) 语法) .
我想从最低级别的函数开始重构和测试,然后逐步向上调用链。我的目标是在进行时将访问类型推出代码。
我理解正确还是我遗漏了什么?
引用@T.E.D,
Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine.
由于这段代码还没有经过测试,我认为你重新编写看起来像用 C 思维编写的代码是完全正确的。但是,您根本不应该提及指针;你建议
function Get_Next(stateInfoPtr : State_Info_Type) return integer;
但这样会更好
function Get_Next(stateInfo : State_Info_Type) return integer;
甚至(IMO)为
function Get_Next(State_Info : State_Info_Type) return Integer;
使用更标准的 Ada 样式!我的编辑器(Emacs,但 GPS 也可以这样做)会即时将 state_info
更改为 State_Info
。
作为事后的想法,您可以完全摆脱 State_Info_Type_Pointer
。你提到 .all
,所以我猜你有
SITP : State_Info_Type_Pointer := new State_Info_Type;
... set up components
Next := Get_Next (SITP.all);
但是
SIT : State_Info_Type;
... set up components
Next := Get_Next (SIT);
我认为原作者,可能还有 OP 遗漏了一点,即 Ada 参数模式的工作原理。
引用@T.E.D
Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine.
Ada 会自动执行此操作,并将参数模式作为描述信息流的一种方式(这不是 C 样式引用/值难题)。看到有用的wikibook.
让我担心的是,您继承的代码看起来像作者使用显式 access
参数类型作为使函数产生副作用的一种方式(在 Ada 中通常被认为是一件坏事 - World ).
我的建议是将您的函数更改为:
function Get_Next(State_Info : in State_Info_Type) return Integer;
看看编译器是否告诉您您是否正在尝试修改 State_Info
。如果是这样,您可能需要将函数更改为这样的过程:
procedure Get_Next(State_Info : in out State_Info_Type;
Result : out Integer);
这显式显示了信息流,无需知道寄存器大小或 State_Info_Type
的大小。
顺便说一句,Ada 2012 将允许您拥有具有 in out
个参数的函数。
我不推荐这样做,但您可以使用“地址”获取指向 Ada 83 中变量的指针。
然后您可以使用覆盖(同样这都是 Ada83 的东西)来实现访问...
function something(int_address : Address) return integer
is
x : integer;
for x'address use int_address;
begin
-- play with x as you will.