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

时间:2015-06-14 04:54:58

标签: c++ c storage-class-specifier

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

每当我们在没有明确提及任何存储类的情况下声明变量时,分配给它的默认存储类型本身就是“auto”。

所以,我的问题是,为什么不将每个变量声明为'register'存储类 - 如果没有可用的寄存器,它将被视为默认的'auto'类本身 。幸运的是,如果寄存器可用,那么它将存储在一个寄存器中。我明白我们不能使用&运算符更长,但如果我使用指针和地址怎么办?我可以使用'register'存储类声明这些变量吗?因为这似乎是一种不好的做法。

编辑:我在网上搜索过,但是“地址不可用”是唯一提到的一点。为什么不能用'register'声明其余的变量。

2 个答案:

答案 0 :(得分:6)

您无法制作所有变量register, 因为C(和(C ++)语言规范明确禁止获取register变量的地址。

但是, register限定符在今天的optimizing compilers GCCClang/LLVM以及这些编译器中没有任何作用我们可以愉快地自由地使用机器寄存器来处理不合格register的变量,甚至可以在内存中(不在机器寄存器中)保存一个限定为register的变量。基本上编译器忽略 register限定符(除了禁止获取其地址)。它具有复杂的register allocation算法和启发式算法。给定变量可能会保留在机器寄存器中,用于功能代码的某些部分,并放在内存中以供其他部分使用。

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

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

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

答案 1 :(得分:3)

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

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

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