我正在重构一些最初使用访问类型编写的代码,但尚未经过测试。我发现访问类型在Ada中很麻烦,因为它们只能引用动态分配的项目,并且显然不允许引用在编译时定义的项目。 (这是Ada83。)
但现在我来到这样的功能:
function Get_Next(stateInfo : State_Info_Access_Type) return integer;
我知道我可以轻松传递访问类型的参数“内容”而不是访问指针本身,所以我正在考虑将其写为
function Get_Next(stateInfoPtr : State_Info_Type) return integer;
其中State_Info_Type是State_Info_Access_Type引用的类型。
使用这个重构,出于所有意图和目的,我认为我仍然真正传递了一个隐含的指针回到内容(使用 .all )语法。)
我想重构并测试从最低级别的函数开始,逐步调用调用链。我的目标是在我去的时候将访问类型推出代码。
我是否正确理解这一点,或者我错过了什么?
答案 0 :(得分:4)
我认为原作者和OP可能缺少一点,即Ada参数模式如何工作。
引用@ T.E.D
我所知道的每个Ada编译器都会通过引用传递大于适合机器寄存器的对象。它是编译器,而不是参数传递mechanisim的细节,它强制不会将数据写回例程。
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
参数的功能。
答案 1 :(得分:3)
引用@T.E.D,
我所知道的每个Ada编译器都会通过引用传递大于适合机器寄存器的对象。它是编译器,而不是参数传递mechanisim的细节,它强制不会将数据写回例程。
由于此代码尚未经过测试,我认为您完全正确地修改看起来像用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);
答案 2 :(得分:0)
我不建议这样做,但你可以使用'地址来获取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.