使用寄存器存储class声明变量时使用了多少个寄存器?

How many registers are used when a variable is declared using register storage class?

我的问题很简单,对于使用 register 存储 class 声明的变量,C 编译器将使用多少个寄存器: register int a。我读过这个答案 How many register and what kind of register are available for the storage class REGISTER in c language 但不太明白。我知道它可能依赖于实现,但是这个寄存器是有限的,所以编译器什么时候会忽略声明或者会产生错误?

C11仍然支持register:

A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.

注释中:

The implementation may treat any register declaration simply as an auto declaration.

那么会用到多少个寄存器呢?一种可能的答案是 'none',因为关键字可能会被忽略。

也就是说,在实践中,任何现代平台上的实现都很少会定义 int 宽度大于典型平台 'word' 的宽度。因此,如果一种实现尊重 register int a;,则 register int a 不太可能分配给多个寄存器,并且 register int a 可能是 0,1 或 2 个寄存器。

当然,在某些硬件上,并非所有寄存器的大小都相同,有时不同的指令将寄存器视为单独的或联合的。多少个寄存器可能没有意义。

正如其他人指出的那样,在 C 中广泛不鼓励使用关键字。事实上,它的含义现在已从 C++ 中删除(尽管关键字保留为保留)。

我认为这在 C 语言中会很严苛,因为 C 语言仍然关注微控制器环境,在这种环境中,程序员最想指定此类细节。

综上所述 'back in the day'(25 年前)我使用的编译器忽略了 register 但分配了前 2 个(我认为)声明的变量用作寄存器的循环计数器并在在有问题的情况下,函数中的第三个循环最长,并且通过首先声明大循环索引显着提高了性能。

这一切似乎是很久以前的事了,没有人应该把它当作现代体验。

register建议编译器尽可能将变量保存在寄存器中。但是现代编译器只是忽略它。所以回答你的问题 - 它可以是零或更多,编译器将根据使用的优化选项来决定。

一些编译器有特殊形式的绑定变量到寄存器。

gcc 版本

       register int *foo asm ("r12");

可以是全局绑定,也可以是局部绑定。

全局绑定:寄存器变量在整个程序执行过程中保存在寄存器中,寄存器从编译器寄存器池中取出。它可以降低编译器优化的效率。

局部绑定:寄存器变量仅在函数范围内绑定到寄存器。

但是不保证没有-ffixed-reg选项编译的库例程会保持这个寄存器不受影响。 setjump & longjump 也是如此,因为寄存器内容的恢复是机器特定的。

需要深入了解机器代码生成才能有效地使用它。现在很少使用了。使用示例 - 减少响应中断请求等的延迟。