Ada 中的普通整数和别名整数有什么区别?

What's the difference between a normal Integer and an aliased Integer in Ada?

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

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

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

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

在 Ada 中,只要存在指向变量的访问值,就需要“别名”关键字的更重要原因是为了让编译器、人类 reader 和静态分析工具明白这一点可以通过访问值访问哪些变量。所以对你,程序员,唯一的区别是你不能使用 var'Access,除非“var”被标记为“aliased”。 “var”存储在哪里应该是编译器的事。

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

不同之处在于您可以使用 'Access 别名变量而不是普通变量。至于它们的存储位置,普通变量可以存储在编译器喜欢的任何地方;理论上,该位置甚至可以在执行期间发生变化。别名变量必须存储在 'Access 有意义的地方,并且必须在变量的生命周期内一直留在那里。

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