正常整数和Ada中的别名整数有什么区别?

4
我仍然对var : Integer;var : aliased Integer;之间的区别感到困惑。根据维基百科,"如果你想从任何变量中取出访问权限,你需要告诉编译器变量需要在内存中而不是在寄存器中。"寄存器难道不也是内存吗?所以一直困扰我的真正问题是var : Integer;var : aliased Integer;被存储在哪里。

今天已经标记为安全,防止意外指针访问。 - user1818839
2个回答

10
Wikibooks的答案适用于大多数当前的通用计算机,其中寄存器是处理器的一部分而不是存储器(RAM)的一部分,并且寄存器没有内存地址,因此不能被指针“指向”或者在Ada中被称为“访问值”。
一些微控制器,比如Intel-8051体系结构,将寄存器映射到内存位置,在这样的机器上,别名变量可以存储在寄存器中。但是,它必须总是存储在那个寄存器中,以便它始终具有相同的地址,并且所有指向它的指针在变量存在的时间内保持有效。编译器通常不想将寄存器专用于变量,因为寄存器更适用于临时值的工作存储。
虽然C语言有一个“register”关键字,可以用来提示编译器程序员认为将某个变量存储在某个寄存器中会很有益(通常是为了速度),但是许多编译器今天忽略了那个关键字,并使用自己的分析来决定哪些变量应该存储在寄存器中,以及何时存储。 C编译器通常检测代码是否获取变量的地址("&"运算符)并使用该信息来避免将该变量存储在寄存器中(除非非常暂时)。
在Ada中,需要“别名”关键字的更重要的原因是使编译器、人类读者和静态分析工具清楚地知道哪些变量可以通过访问值进行访问。因此,对您作为程序员来说唯一的区别是,除非将“var”标记为“别名”,否则无法使用var'Access。存储“var”的位置应该由编译器处理。
Ada编译器需要这些信息的一个原因是Ada子程序可以在其中嵌套子程序。这些嵌套的子程序可以访问包含子程序的变量(如果变量在嵌套子程序之前声明),如果变量没有标记为别名,则编译器可以更好地优化嵌套子程序的代码,即将变量的值在某个寄存器中保持一段时间,而不担心程序的其他部分可能会尝试通过访问值“幕后”访问变量。

非常感谢!你解释得非常清楚 :) - Amben Uchiha
C语言中的"register"关键字并不像你所认为的那样过时。当使用gcc编译器时,如果程序员适当地使用"register"关键字,并且使用"-O0"标志,它通常可以生成相当不错的代码,但否则将生成糟糕的代码。 - supercat

4
区别在于您可以获取别名变量的 "Access",而不能获取普通变量的 "Access"。至于它们存储的位置,普通变量可以存储在编译器喜欢的任何地方;从理论上讲,甚至在执行期间位置也可能发生变化。别名变量必须存储在适当的位置,以使“Access”有意义,并且必须在变量的生命周期内保留在那里。
但是,这不仅仅涉及是否可以获取 "Access"。编译器可以利用这种信息进行无法实现的优化。在 C 中,所有变量都是别名变量,并且可以使用一元 "&" 运算符获取它们的指针;在 Ada 中,只有标记为 "aliased" 的变量是别名变量。"C vs Ada: Arguing Performance Religion 讨论了 Tartan Ada(83)编译器生成比 Tartan C 编译器更快代码的原因,而 C 的指针到所有内容的方法的负面影响是其中之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接