【问题标题】:Ada Function Parameter as Access Type or NotAda 函数参数是否作为访问类型
【发布时间】:2015-06-24 16:38:11
【问题描述】:

我正在重构一些最初使用访问类型编写但尚未测试的代码。我发现访问类型在 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)语法)。

我想从最低级别的函数开始重构和测试,沿着调用链向上工作。我的目标是随时将访问类型从代码中推出。

我理解正确还是遗漏了什么?

【问题讨论】:

    标签: ada


    【解决方案1】:

    我认为原作者和可能的 OP 遗漏了一点,即 Ada 参数模式的工作原理。

    引用@T.E.D

    我所知道的每个 Ada 编译器都通过引用传递大于机器寄存器大小的对象。是编译器,而不是参数传递机制的细节,强制不将数据写回例程。

    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 参数的函数。

    【讨论】:

    • 我认为第一行中的“你”是指我。吉姆的问题你很可能是对的,在这种情况下,你的答案将上升到顶部,而“你”将不再有意义!
    • 为清晰起见编辑:)
    【解决方案2】:

    引用@T.E.D

    我所知道的每个 Ada 编译器都通过引用传递大于机器寄存器大小的对象。是编译器,而不是参数传递机制的细节,强制不将数据写回例程。

    由于此代码尚未经过测试,我认为您完全正确地重新编写看起来像是用 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);
    

    【讨论】:

    • “我所知道的每个 Ada 编译器都通过引用传递大于机器寄存器大小的对象。”——这是错误的。某些平台上的 ICC Ada 将在寄存器中传递已知大小的小记录或数组,前提是它们可以容纳 4 个寄存器。
    【解决方案3】:

    我不建议这样做,但您可以使用“地址”获取指向 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.

    【讨论】:

    • 没有真正回答问题...这是一个问答网站!
    • OP 说...“我发现访问类型在 Ada 中很麻烦,因为它们只能引用动态分配的项目,并且显然不允许引用在编译时定义的项目。(这是 Ada83。)”我正在对他原来的前提进行更正 - 这不在本网站的范围内吗?
    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多