【问题标题】:What's the difference between a normal Integer and an aliased Integer in Ada?Ada 中的普通整数和别名整数有什么区别?
【发布时间】:2021-04-03 11:45:04
【问题描述】:

我仍然对var : Integer;var : aliased Integer; 之间的区别感到困惑。根据 wikibooks “如果你想从任何变量中获取访问权限,你需要告诉编译器该变量需要在 memory 中并且不能驻留在 register 中”。寄存器不也是内存吗?所以一直困扰我的真正问题是var : Integer;var : aliased Integer; 的存储位置。

【问题讨论】:

  • “今天标记为安全,免受意外指针访问”

标签: types ada


【解决方案1】:

Wikibooks 的答案适用于大多数当前的通用计算机,其中寄存器是处理器的一部分,而不是内存 (RAM) 的一部分,并且寄存器没有内存地址,因此不能被指针“指向”,或者“访问值”,因为它们在 Ada 中被称为。

某些微控制器(例如 Intel-8051 架构)会将寄存器映射到内存位置,并且在此类机器中,别名变量可以存储在寄存器中。但是,它必须始终存储在该寄存器中,以便它始终具有相同的地址,并且只要变量存在,所有指向它的指针都保持有效。编译器通常不希望将寄存器专用于变量,因为寄存器作为临时值的工作存储更有用。

虽然 C 语言有一个“寄存器”关键字,可用于向编译器提示程序员认为将某个变量存储在某个寄存器中会有益(通常是为了提高速度),但如今许多编译器忽略了该关键字,并使用他们自己的分析来决定哪些变量应该保存在寄存器中以及何时保存。 C 编译器通常会检测代码是否曾经获取变量的地址(“&”运算符)并使用该信息来避免将该变量存储在寄存器中(非常临时除外)。

在 Ada 中,每当可能存在指向变量的访问值时都需要“aliased”关键字的更重要原因是让编译器、人类读者和静态分析工具清楚哪些变量可以通过以下方式访问访问值。因此,程序员的唯一区别是,除非“var”被标记为“aliased”,否则您不能使用 var'Access。 “var”存放在哪里应该是编译器的事。

Ada 编译器需要该信息的一个原因是 Ada 子程序中可以有嵌套的子程序。这些嵌套子程序可以访问包含子程序的变量(如果变量是在嵌套子程序之前声明的),如果变量被not标记为别名,编译器可以通过以下方式更好地优化嵌套子程序的代码确实,将变量的值保存在某个寄存器中一段时间​​,而不必担心程序的其他部分可能会尝试通过访问值“在幕后”访问变量。

【讨论】:

  • 非常感谢!你解释得很好:)
  • C 的“注册”关键字并不像您建议的那样过时。当 gcc 与-O0 标志一起使用时,如果程序员适当地使用register,它通常可以生成半途而废的代码,否则会生成糟糕的代码。
【解决方案2】:

不同之处在于您可以使用别名变量的'Access 而不是普通变量。至于它们的存储位置,普通变量可以存储在编译器喜欢的任何位置;从理论上讲,位置甚至可以在执行过程中改变。别名变量必须存储在'Access 有意义的位置,并且必须在变量的整个生命周期内保留在那里。

但是,这不仅仅是您是否可以接受'Access。编译器可以使用这种信息来进行没有它就不可能进行的优化。在 C 中,所有变量都有别名,您可以使用一元“&”运算符获取指向它们的指针;在 Ada 中,只有标记为 aliased 的变量是别名。 "C vs Ada: Arguing Performance Religion 讨论了为什么 Tartan Ada (83) 编译器生成的代码比 Tartan C 编译器更快,而 C 的指针指向一切方法的负面影响是部分原因。

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 2015-06-27
    • 2012-01-29
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多