gcc中的全局寄存器变量
最近,我在一次采访中被问及全局寄存器变量。我把所有全局变量都存储在数据段中的说法搞砸了。但后来我被问及GCC。在采访后,我得出结论,GCC支持全局寄存器变量gcc中的全局寄存器变量,c,gcc,C,Gcc,最近,我在一次采访中被问及全局寄存器变量。我把所有全局变量都存储在数据段中的说法搞砸了。但后来我被问及GCC。在采访后,我得出结论,GCC支持全局寄存器变量 #include<stdio.h> register int var asm("ebx"); //storing global variable in register explicitly int main(void) { ....... } #包括 寄存器int var asm(“ebx”)//在寄存器中显式存储全局
#include<stdio.h>
register int var asm("ebx"); //storing global variable in register explicitly
int main(void)
{
.......
}
#包括
寄存器int var asm(“ebx”)//在寄存器中显式存储全局变量
内部主(空)
{
.......
}
这里是链接
但现在我对它的生存期和作用域感到困惑,以及它是作为普通全局变量还是作为寄存器变量工作?另外,gcc上是否有任何方法或一些命令,以便我们确保编译器不会简单地忽略
register
关键字并将其存储在实际的register中?正如许多人指出的那样,全局保留寄存器通常是个坏主意。我相信这里的初衷是(来自:
这在诸如编程语言之类的程序中可能很有用
具有可访问的两个全局变量的解释器
经常
这是否真的有用,或者只是让事情变得更糟,可能只能在特定情况下确定。在你的情况下(面试问题),这并不重要
像这样的声明的范围是看到该声明的所有内容,正如您对任何全局声明所期望的那样
然而,实现有点棘手。再次引用文件:
在特定寄存器中定义全局寄存器变量
完全注册用于此用途,至少在当前
编译。登记册不分配用于任何其他目的
当前编译中的函数,并且不会保存和
由这些功能恢复
因此,使用该声明编译的所有代码都将保留用于该用途的寄存器。但是,如果您链接到未使用此保留编译的其他代码,则不会为此目的保留该代码
这些文档提供了一个关于qsort的极好示例。如果您的代码是使用此声明编译的,然后它从c运行时调用qsort(可能不是使用此声明编译的),然后qsort调用回您的代码(对于比较函数),那么回调函数无法确保qsort在调用比较函数之前没有踩到寄存器上
如果调用任何库函数都会在寄存器上跺脚,那么这怎么可能起作用呢?再次从文档中:
选择一个通常按功能保存和恢复的寄存器
在您的计算机上调用,以便库例程不会破坏它
即便如此:
从信号访问全局寄存器变量是不安全的
处理程序,或来自多个控制线程,因为系统
库例程可能会暂时将寄存器用于其他用途
(除非您专门为手头的任务重新编译它们)
关于你问题的最后一部分:
编译器不会简单地忽略register关键字,而是存储在
实际寄存器
我不知道你的意思。如果(不知何故)编译器忽略了
asm(“ebx”)
,那么它将不会存储在寄存器中。使用此功能的全部目的是确保var
存储在实际的ebx寄存器中。您不能通过调试器尝试一下吗?@MrSykkox:您能帮我解决这个问题吗?你能回答我的第一个问题吗?我会很感激的。我不确定这一生会是什么样子,但我想测试一下。如果您使用的是gdb(-ggdb),则使用调试标志(-g)进行编译。在主代码集中,var=something。在退出前设置断点。并打印寄存器值(info register ebx)。C并不是盲从C++,而是写在墙上。不要在C中使用auto
;不要在新的C代码中使用register
(您可以在旧的C代码中非常安全地删除它)。对全局变量使用register
会将您绑定到特定的C编译器,并且基本上没有任何好处。记住,register
是对编译器的提示,而不是命令;编译器可以根据您的提示随心所欲。使用register
确实会阻止您获取变量的地址,但仅此而已。如果您的面试官试图用有关奇怪的gcc扩展的问题来欺骗您,那么您可能无论如何都不想与这些人合作!