为什么我们不能总是在 C 中使用寄存器存储类?

Why can't we always use the register storage class in C?

本文关键字:寄存器 存储 不能 我们 为什么      更新时间:2023-10-16

我在一本书中读到,每当我们使用存储类声明一个变量作为寄存器时,它就会存储在寄存器中,这取决于它的可用性。如果没有可用的寄存器,则将为其分配默认存储类型"auto"。

每当我们声明一个变量而不明确提及任何存储类时,分配给它的默认存储类型就是"auto"本身。

所以,我的问题是,为什么不将每个变量声明为"寄存器"存储类 - 如果没有可用的寄存器,它无论如何都会被视为默认的"自动"类本身。幸运的是,如果寄存器可用,那么它将存储在一个寄存器中。我知道我们不能再使用 & 运算符了,但是如果我打算使用指针和地址怎么办?那么我可以使用"寄存器"存储类声明这些变量吗?因为这似乎是一种不好的做法。

编辑:我搜索了网络,但"地址不可用"是唯一提到的点。为什么不能用"寄存器"声明其余变量没有提到。

你不能把所有的变量都register,因为 C(和 (C++) 语言规范明确禁止获取 register 变量的地址。

但是,register限定符在当今的优化编译器(如GCC或Clang/LLVM)中没有任何作用,这些编译器将愉快而自由地使用机器寄存器来存储不合格的变量register甚至将合格的变量保留在内存中(不在机器寄存器中)一个合格的变量register。本质上,编译器忽略了register限定符(除了禁止获取其地址)。它具有复杂的寄存器分配算法和启发式算法。给定变量可能保留在机器寄存器中,用于函数代码的某些部分,并放在内存中用于其他部分。

从优化的角度来看,当前的编译器以相同的方式处理autoregister限定变量(因此register限定符是无用的,除了禁止地址运算符)。

还要注意的是,CPU缓存比今天的处理器寄存器重要得多。如果你想手动调整你的 C 代码以提高性能(这通常是一个坏主意,因为编译器做得比你能做的更好),最好处理缓存问题(见这里)。

AFAIK,C 和 C++ 语言的未来版本将正式弃用 register 限定符(就像他们对auto限定符所做的那样),并且未来的语言规范可能会将该关键字重用于其他目的(如 C++11 重用auto)。因此,在源代码中使用register可能是一个错误,因为它可能会使您的代码更难移植到 C 或 C++ 的未来版本。

"register" 关键字只是对编译器的提示,如果可能的话,认为应该比其他变量更快地处理该变量。作为副作用,不允许获取变量的地址,并且寄存器数组是未定义的行为。

任何现代编译器都会尽可能多地使用寄存器,因此不再需要此关键字。编译器也比你更聪明:它可以在程序的一个部分中对变量x使用寄存器,在程序的另一部分中对变量y使用寄存器。或者对结构的五个字段中的两个使用寄存器。所有你甚至不能用注册关键字表达的东西。

使用

寄存器可能并非完全没有意义的唯一情况是,当您有一个看起来比其他变量使用得少得多的变量时,但您知道得更好。即便如此,这也是一个非常大的"可能"。