C 为什么注册变量不能成为全局变量?
当从一个站点读取数据时,你不能生成寄存器类型的全局变量。为什么会这样? 资料来源:C 为什么注册变量不能成为全局变量?,c,global,cpu-registers,micro-optimization,C,Global,Cpu Registers,Micro Optimization,当从一个站点读取数据时,你不能生成寄存器类型的全局变量。为什么会这样? 资料来源: 因为它们在寄存器中。这在术语上是矛盾的。最初,寄存器变量应该存储在处理器寄存器中,但全局变量必须存储在数据或BSS部分中,才能从每个函数访问。如今,编译器并没有严格解释寄存器存储类,因此它主要是出于兼容性原因而保留的。,因为它毫无意义。全局变量在应用程序运行时始终存在。很长一段时间内肯定没有空闲的处理器寄存器;) 理论上,您可以将处理器寄存器分配给全局范围变量-该寄存器只需在程序的整个生命周期内保持分配给该变量即
因为它们在寄存器中。这在术语上是矛盾的。最初,寄存器变量应该存储在处理器寄存器中,但全局变量必须存储在数据或BSS部分中,才能从每个函数访问。如今,编译器并没有严格解释
寄存器
存储类,因此它主要是出于兼容性原因而保留的。,因为它毫无意义。全局变量在应用程序运行时始终存在。很长一段时间内肯定没有空闲的处理器寄存器;) 理论上,您可以将处理器寄存器分配给全局范围变量-该寄存器只需在程序的整个生命周期内保持分配给该变量即可
然而,C编译器在编译阶段通常看不到整个程序——编写C标准是为了使每个翻译单元(大致对应于每个
.C
文件)可以独立于其他单元进行编译(编译后的对象链接到程序中)。这就是不允许全局范围寄存器变量的原因-当编译器编译b.c
时,它无法知道在a.c
中有一个全局变量分配给寄存器(因此b.c
中的函数必须保留该寄存器中的值)。实际上,GCC允许这样做。全局范围内的声明,格式如下:
register int foo asm ("r12");
为全局“foo”分配寄存器“r12”(在x86_64上)。这有很多限制,相应的手册页可能是所有麻烦的全局寄存器变量的最佳参考:
如果您要求使其成为全局的,那么您需要为所有代码和所有源代码保留注册。这是不可能的,所以编译器会给您一个错误,或者只是将其作为存储在内存中的常规变量。register关键字的含义与其名称所表示的含义不同,现在它与处理环境的寄存器没有多大关系。(尽管可能曾经为此选择过它。)唯一限制使用
register
声明的变量的文本是
一元运算符&的操作数
应为功能指示器,
[]或一元数的结果*
运算符,或指定
不是位域的对象,并且
未随登记册一起声明
存储类说明符
因此,它实现了对自动变量(在函数中声明的变量)的限制,因此获取此类变量的地址是错误的。这样的想法是,编译器可以以任何方式表示这个变量,比如寄存器或直接汇编程序值等。作为程序员,您承诺不会获取它的地址。通常,这对全局变量没有多大意义(无论如何,它们有一个地址)
总结如下:
- 否,
关键字不可用 忽略寄存器
- 是的,它只能用于堆栈 变量,如果您想成为标准一致的
这种方法适用于局部寄存器变量,但不适用于全局寄存器变量。为了使全局寄存器变量有用,程序员通常必须告诉编译器哪个寄存器将用于哪个变量,并确保编译器在编译所有模块时知道这些保留,即使那些不使用否则注册。这在嵌入式系统中很有用,特别是对于中断使用的变量,但通常数量非常有限(例如2个左右)在一个系统中允许使用这样的变量。那么我们现在都同意了吗?我们都看到,将一个全局变量作为一个寄存器变量将是一个非常非常糟糕的主意吗?如果原始的C定义没有禁止它,那可能是因为没有人认为任何人会以这种方式实现它——因为他们不应该特别在CI中这样做SC天
此外:现代优化编译器在决定何时在寄存器中保留变量方面比人类做得更好。如果你的编译器做不到,那么你真的需要一个更好的编译器。既然全局变量在堆中?-1表示忽略了
register
关键字,这是错误的。