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