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.