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

问题描述

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

解决方法

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

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

  3. 大约在 1973 年 (Unix V6),register 存储类对于压缩 PDP-11 代码以编译足够小以便内核可以容纳其 64 KiB 空间非常有价值。速度不错,但在那些日子里,它与代码大小有关。

,

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

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

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

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


关键字仍然有一些非常有限的高级“语言律师”用法。也就是说,这样的变量永远不会被占用它的地址。 address-of operator 6.5.3.2 声明(强调我的):

一元 & 运算符的操作数 应该是函数指示符、[] 或一元 * 运算符的结果,或者是指定不是位域的对象的左值,并且未使用寄存器存储类说明符声明

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