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

3

我在一本书中读到,每当我们使用存储类为register声明变量时,它将被存储在寄存器中,前提是有空闲的寄存器可用。如果没有寄存器可用,则会分配默认的auto存储类型。

每当我们声明一个变量而没有明确指定任何存储类型时,默认分配给它的存储类型就是'auto'。

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

编辑:我搜索了网页,但唯一提到的是“地址不可用”。为什么其他变量不能声明为'register'没有被提及。


4
“register”关键字已经过时。现代编译器完全忽略它,除了其语义意义。 - Mysticial
哦,但为什么?为什么被忽略了呢?如果有许多变量,这个存储类在优化期间确实可以提供帮助。 - user3576734
1
因为现代编译器可以比绝大多数人更好地进行寄存器分配。 - Mysticial
3
因为这个标签是C++,所以register在C++11中已被废弃,并将在C++17中移除。 - user657267
1
“地址不可用”并非缺点,而是一种特性。该关键字使您有机会稍微限制变量的使用,并在违反自己的承诺时引发编译时错误。它为编译器提供了减少人类设计师错误的机会。这是一件好事。遗憾的是,C语言没有更多像这样的功能,因为register本身并不足够强大。换句话说,除了同行压力外,没有理由不在任何地方使用它。 - Alex Celeste
显示剩余5条评论
2个回答

6

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

然而,在今天的优化编译器(如GCCClang/LLVM)中,register限定符已经没有任何作用了,这些编译器会自由地使用机器寄存器来存储未被声明为register的变量,甚至将声明为register的变量存储在内存中(而非寄存器)。实际上,编译器忽略了register限定符(除了禁止获取其地址)。它具有复杂的寄存器分配算法和启发式方法。某个变量可能会在函数代码的某些部分保留在机器寄存器中,并在其他部分放入内存中。

从优化的角度来看,当前编译器以相同的方式处理autoregister限定的变量(因此register限定符是无用的,除了禁止取地址运算符)。
还要注意的是,CPU缓存处理器寄存器今天更重要。如果您想为性能调整您的C代码(这通常是一个坏主意,因为编译器比您做得更好),最好注意缓存问题(参见this)。
据我所知,未来版本的C和C++语言将正式弃用register限定符(就像它们对auto限定符所做的一样),并且未来的语言规范可能会重新使用该关键字用于其他目的(就像C++11重新使用了auto)。因此,在您的源代码中使用register可能是一个错误,因为它可能使您的代码难以移植到未来的C或C++版本。

如果我不打算在地址上工作(正如我在问题中已经指出的那样),那么我可以使用寄存器存储类吗? - user3576734
4
可以,但没有用。 - Basile Starynkevitch
6
如果你在新代码中使用register关键字,除了毫无作用之外,其他C/C++程序员还会指着你笑话。 - Ross Ridge
你认为在自动变量或全局变量上使用 register 关键字会有什么问题吗?这将使编译器假定在创建指向该变量的指针之外的上下文中,没有指针与其别名相同,从而使编译器假定在 register int x, y; get_two_numbers(&x, &y); 之后,编译器可以将 xy 视为不存在任何外部指针可能存在的变量。 - supercat

3
"register"关键字只是向编译器暗示您认为变量应该尽可能快地处理。作为副作用,不允许获取变量的地址,并且register数组是未定义的行为。
现代编译器将尽可能使用寄存器,因此不再需要此关键字。编译器比您更聪明:它可以在程序的一个部分中使用寄存器来处理变量x,在另一个部分中使用寄存器来处理变量y。或者使用寄存器处理结构体的五个字段中的两个字段。这些都是使用"register"关键字无法表达的事情。
唯一的情况是当您有一个看起来使用次数比其他变量少很多的变量时,使用register可能不完全没有意义,但即使在这种情况下,“register”也只会有很小的影响。

最后一段是错误的:使用优化编译器,使用“register”关键字不会对生成的代码产生任何影响。 - Basile Starynkevitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接