寄存器变量的地址

Nav*_*een 15 c c++ register-allocation keyword

在C中,我们不能使用&来查找寄存器变量的地址,但在C++中我们也可以这样做.为什么它在C++中合法而在C中不合法?有人可以深入解释这个概念.

And*_*ton 31

以下是C99标准(pdf)第6.7.1节(脚注101)的摘录:

实施可以将任何register声明简单地视为auto声明.但是,无论是否实际使用了可寻址存储,使用存储类说明符寄存器声明的对象的任何部分的地址都无法显式(通过使用&6.5.3.2中讨论的一元运算符)或隐式(通过将数组名称转换为指针,如6.3.2.1中所述.因此,唯一可以应用于使用存储类说明符声明的数组的运算符registersizeof.

从第7.1.1节,C++标准的第3段(pdf):

一个register说明符具有相同的语义的auto一个提示,如此声明的对象将被频繁使用的执行一起符.[注意:提示可以忽略,在大多数实现中,如果采用对象的地址,它将被忽略. - 尾注]

有趣的花絮 register

C++组(WG21)想要弃用register:

register关键字提供的功能非常少,仅提供一条通常会被忽略的提示.它应该在此版本的标准中弃用,将保留的名称释放出来用于未来的标准,就像auto这次重复使用同样无用的一样.

2009年3月会议记录:

CWG的共识是赞成弃用register.

在会议上了解register C99小组(WG14)所说的内容(pdf):

一般同意弃用" auto"关键字.我们是否应该要求WG21回到之前使用的" register"(没有地址)?不,这不会与WG21一起飞行.

  • WG21的章程中明确指出C++和C之间没有任何差异,C标准引入了C++的几个特性,这些特性与现有的C用法没有冲突,比如单行注释. (5认同)
  • 好极了.另外要添加到我的C和C++之间的任意差异列表中.我很想听听改变这个的理由. (2认同)
  • 在过去,程序员将变量标识指定为寄存器变量是有意义的,因为编译器不是那么好.现在,编译器几乎总是比编程器更好地进行优化,因此将其更改为提示符合编译器技术的进步. (2认同)
  • 我并不认为"注册"很有用,只是在C和C++之间存在任意差异是一个坏主意."寄存器"的C++版本是任意不同的,但没有更多用处.它只是增加了那些用C++编译器编译的代码,但没有用C编译器编译.我(天真地)期望C和C++标准趋于随时间收敛,或者至少不会分歧. (2认同)
  • @Mark Bessey:他们是两种不同的语言.我不知道你对*不同语言的期望*,但分歧对我来说听起来非常合理.任意差异很好 - 因为它们*不同*. (2认同)

Tyl*_*nry 5

register关键字只是一个提示,可以忽略.大多数C++编译器始终忽略它,但是如果你获取变量的地址或者创建对它的引用,任何C++编译器都会忽略它.

在另一方面,C++编译器不具备忽略"注册"只是因为你采取的变量的地址.从理论上讲,编译器可以将它存储在一个寄存器中,并为您提供一些魔法指针值,该值以某种方式映射到幕后的寄存器,但这样做的工作量很少,因此没有编译器(我知道)做那样的事.

由于寄存器在C中也是可忽略的,因此我怀疑对寄存器变量地址的明确禁止只是为了减轻C编译器的检查负担.

C++标准的相关部分是7.1.1.3:

寄存器说明符具有与auto说明符相同的语义,以及对如此声明的对象将被大量使用的实现的提示.[注意:提示可以忽略,在大多数实现中,如果采用对象的地址,它将被忽略. - 尾注]


小智 5

抱歉超级迟到的答案.

问题在于,在C中,register最初意味着将值存储在寄存器中,这就是为什么只能int并且char可以用于它.但随着时间的推移,特别是标准的C++,它扩展到"快速访问"而不是"在CPU注册".所以在C++中,数组可能是一种register类型,但我们知道不可能将数组存储在CPU寄存器中.因此,在逻辑上可以解决C++寄存器(在上面的意义上),但如果值实际上在CPU寄存器中仍然没有意义.