C 编译器忽略寄存器声明的原因

Reasons a C Compiler Ignores register Declaration

C 编译器忽略 register 声明的原因是什么?我知道这个声明对于现代编译器基本上没有意义,因为它们在适当的时候将值存储在寄存器中。我正在学习计算机体系结构 class,所以了解为什么旧编译器会出现这种情况很重要。

"A register declaration advises the compiler that the variable in question will be heavily used. The idea is that register variables are to be placed in machine registers, which may result in smaller and faster programs. But compilers are free to ignore the advice." ~ The C Programming Language by Brian W. Kernighan and Dennis M. Ritchie

谢谢!

历史上的 C 编译器可能只“聪明”(复杂)到足以一次查看一个 C 语句,就像现代的 TinyCC. Or parse a whole function to find out how many variables there are, then come back and still only do code-gen one statement at a time. For examples of how simplistic and naive old compilers are, see Why do C to Z80 compilers produce poor code? - 显示的一些示例 可能 已针对特殊的简单情况进行了优化,但并未进行优化。 (尽管 Z80 和 6502 是非常差的 C 编译器目标,因为(与 PDP-11 不同)“指针”不是您可以只保存在寄存器中的东西。)

启用优化后,现代编译器确实有足够的 RAM(和编译时)可用于使用更复杂的算法来为整个函数映射寄存器分配,并在内联后做出正确的决定。 (例如,将程序逻辑转换为 SSA form.) See also https://en.wikipedia.org/wiki/Register_allocation

register关键字变得毫无意义;编译器已经可以注意到何时未获取变量的地址(register 关键字不允许)。或者当它可以优化地址获取并将变量保留在寄存器中时。

TL:DR:现代编译器不再需要手动操作以按照 register 关键字提示的方式完全应用 as-if 规则。

他们基本上总是将所有内容保存在寄存器中,除非被迫将其溢出回内存,除非您禁用优化以实现完全一致的调试。 (因此您可以在断点处停止时使用调试器更改变量,甚至可以在语句之间跳转。)


有趣的事实:Why does clang produce inefficient asm with -O0 (for this simple floating point sum)? 显示了一个示例,其中 register float 使现代 GCC 和 clang 创建更高效​​的 asm 禁用优化