我的问题很简单,C 编译器将使用多少个寄存器来声明使用存储类声明register
变量:register int a
.我已经阅读了这个答案 有多少寄存器和什么样的寄存器可用于 c 语言的存储类 REGISTER,但听不懂太多。我知道它可能依赖于实现,但是这个寄存器是有限的,那么编译器什么时候会忽略声明还是会生成错误?
C11 仍然支持register
:
具有存储类的对象的标识符声明 说明符寄存器建议对对象的访问速度与 可能。这些建议的有效程度是 实现定义。
在注释中:
实现可以将任何寄存器声明简单地视为 自动声明。
那么将使用多少个寄存器呢?一个可能的答案是"无",因为关键字可能会被忽略。
也就是说,在实践中,任何现代平台上的实现都很少使用宽度大于典型平台"单词"宽度来定义int
。因此,如果实现符合register int a;
则不太可能register int a
分配给多个寄存器,register int a
可能是 0,1 或 2 个寄存器。
当然,在某些硬件上,并非所有寄存器的大小都相同,有时不同的指令将寄存器视为单独的或连接的。多少寄存器可能没有意义。
正如其他人指出的那样,在 C 中广泛不鼓励使用该关键字。事实上,它的含义现在从C++中删除了(尽管关键字保留为保留(。
我认为这在 C 语言中会很苛刻,因为 C 语言仍然着眼于程序员最接近想要决定这些细节的微控制器环境。
所有这些都说"回到过去"(25 年前(,我使用了一个编译器,它忽略了register
但将前 2 个(我认为(声明的变量用作循环计数器分配给寄存器,在有问题的情况下,函数中的第三个循环最长,并且通过首先声明大循环索引显着提高了性能。
这一切似乎都是很久以前的事了,没有人应该把它当作现代经验。
register
是编译器在可能的情况下将变量保留在寄存器中的建议。但是现代编译器只是忽略了它。所以回答你的问题 - 它可以是零或多个,编译器将根据使用的优化选项决定。
一些编译器具有特殊形式的狂欢变量到寄存器。
海湾合作委员会版本
register int *foo asm ("r12");
它可以是全局绑定或本地绑定。
全局绑定:寄存器变量保存在寄存器中用于整个程序执行,寄存器从编译器寄存器池中取出。它会使编译器优化的效果降低。
本地绑定:寄存器变量仅在函数范围内绑定到寄存器。
但不能保证在没有-ffixed-reg
选项的情况下编译的库例程不会使此寄存器不受影响。setjump
和longjump
也是如此,因为寄存器内容的恢复是特定于机器的。
需要深入了解机器代码生成才能有效地使用它。现在很少使用。使用示例 - 减少响应中断请求的延迟等。