C:为什么使用 register 被认为是不好的做法?

C: Why would using register be considered bad practice?

我在 SO 上读到一个问题(不幸的是我不记得这个问题),两个不应该使用的关键字是 gotoregister。 现在,在此之前我什至不知道 register 到底是什么,所以我查了一下,发现另一个问题 here 显示了寄存器的一些用途。当然,寄存器值有其缺点,但我也看到了一些用途。另外,编译器总是可以否决实际使用寄存器的选择。因此,如果您知道使用 register 时的限制,为什么不使用它们呢?

  1. 使用大约 1990 年以前的编译器并大量使用 register 可能并且很可能会阻碍他们对程序员过于信任并生成非最佳代码。

  2. 大多数(几乎所有)编译器现在都“聪明”到足以确定给定的 register 变量集是否有用并且可能完全忽略它们。

  3. 大约在 1973 年 (Unix V6),register 存储 class 对于压缩 PDP-11 代码非常有价值,可以编译得足够小,以便内核可以适应它的 64 KiB space。速度还可以,但在那个年代,就是代码大小。

register 主要是一个多余的关键字,历史上曾用于手动优化代码。非常老的编译器有时太笨了,无法意识到一个没有地址的变量通常可以存储在 CPU 寄存器中而不是堆栈中,这是一个重大的性能改进。

寄存器不仅是计算机中最快的内存类型,而且比堆栈所在的 RAM 快得多。但是如果在寄存器中分配,编译器也可以省去pushing/popping栈上变量的额外代码。

但是,正常的现代 C 程序不应使用 register,因为在确定将某个变量分配到何处时,编译器现在比程序员更有能力。自 1990 年代中期以来,该关键字已“事实上”过时,尽管它尚未被 C 标准正式标记为过时。

因此,如果您遇到包含 register 的代码,它要么非常旧,要么(更有可能)程序员在尝试手动优化某些内容时并不知道他们在做什么。


关键字仍然有一些非常有限的高级“语言律师”用法。也就是说,这样的变量永远无法获取其地址。运算符 6.5.3.2 的地址(强调我的):

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

这在某些情况下可能很重要,例如确定访问具有不确定值的未初始​​化变量是未定义的行为还是仅仅是未指定的行为。参见 (Why) is using an uninitialized variable undefined behavior?