当前位置:  开发笔记 > 编程语言 > 正文

为什么address-of operator('&')可以与在C++中使用寄存器存储类说明符声明的对象一起使用?

如何解决《为什么address-ofoperator('&')可以与在C++中使用寄存器存储类说明符声明的对象一起使用?》经验,为你挑选了2个好方法。

在C编程语言中,我们不允许将address-of运算符(&)与使用寄存器存储类说明符声明的变量一起使用.

它给 error: address of register variable ‘var_name’ requested

但是如果我们制作一个c ++程序并执行相同的任务(即使用&with寄存器存储变量),它不会给我们任何错误.

例如.

#include 
using namespace std;
int main()
{
    register int a;
    int * ptr;
    a = 5;
    ptr = &a;
    cout << ptr << endl;
    return 0;
}

输出: -

0x7ffcfed93624

那么这必须是C++的一个额外功能,但问题在于C和C++中寄存器类存储的区别.



1> Alan Stokes..:

在C++中故意删除了取得地址的限制 - 没有任何好处,它使语言更复杂.(例如,如果绑定对register变量的引用会发生什么?)

register关键字一直没有多大用处了很多年-编译器是在搞清楚该怎么把寄存器本身非常好.实际上,在C++中,该关键字目前已被弃用,最终将被删除.


@alanstokes寄存器没有地址.为了获得地址,编译器需要将其放在内存中.为了使其具有任何意义,它还必须在所述地址的接收者可以访问它并随后将其读回的任何时刻更新存储器中的该值.这听起来很像是忽略了暗示,不是吗?
我将扮演魔鬼的拥护者:一些实现 - 嵌入式实现 - 大多数 - 将`register`作为实际命令,而不仅仅是一个提示.这是因为你经常需要控制寄存器; 程序员_know_他们在做什么.我问了一个问题是否允许,我会无耻地给出[链接](http://stackoverflow.com/questions/28928674/can-an-implementation-consider-hints-as-actual-statements).
C中的register关键字表示您不能获取变量的地址,这反过来暗示变量不会被任何指针别名.这可能允许编译器执行它本来无法执行的优化,*即使*它没有将变量放在寄存器中.(是的,现代编译器非常聪明,但为它们提供更多信息可以让它们变得更聪明*.程序员*确实*有他们缺乏的信息.)当然,如果C++*确实*允许你采取的地址变量,然后寄存器在该语言中不太有用.

2> sqykly..:

register存储类最初暗示编译器的变量,以便有资格为被如此频繁,保持它的价值在内存将是一个性能缺点使用.在广阔的大多数CPU架构(也许不是SPARC?甚至不能肯定有一个反例)从内存中没有先加载一个或两个不能执行两个变量之间的任何操作成其寄存器.将变量从存储器加载到寄存器中并在操作后将它们写回存储器所需的CPU周期比操作本身多出许多倍.因此,如果频繁使用变量,则可以通过为其预留寄存器而不打扰存储器来实现性能增益.

但是,这样做有各种各样的要求.每种CPU架构都有许多不同之处:

所有处理器都有固定数量的寄存器,但每个处理器型号都有不同的编号.在80年代,你可能有4个可以合理地用于register变量.

大多数处理器不支持每个指令使用每个寄存器.在80年代,只有一个可用于加法和减法的寄存器并不常见,你可能无法使用相同的寄存器作为指针.

调用约定规定了不同的寄存器集,这些寄存器可能被子程序(即函数调用)覆盖.

寄存器的大小因处理器而异,因此存在register变量不适合寄存器的情况.

由于C旨在独立于平台,因此标准无法强制执行这些限制.换句话说,虽然可能无法为register只有4个机器寄存器的系统编译20个变量的过程,但C程序本身不应该是"错误的",因为没有逻辑上的原因,机器不能有20个寄存器.因此,register存储类始终只是一个提示,如果特定目标平台不支持它,编译器可以忽略它.

无法引用寄存器是不同的.阿register特别不保存在存储器中更新,不保持当前如果改变到存储器制成; 这就是存储类的重点.由于它们不打算在内存中具有保证的表示,因此它们在逻辑上不能在内存中具有对可能获得指针的外部代码有意义的地址.寄存器没有自己CPU的地址,并且它们几乎从不具有任何协处理器可访问的地址.因此,任何试图获得对基准register总是一个错误.C标准可以轻松地执行这一规则.

然而,随着计算的发展,一些趋势的发展削弱了register存储类本身的目的:

处理器带来了更多的寄存器.今天你可能至少有16个,它们可能在大多数情况下可以互换使用.

多核处理器和分布式代码执行已经变得非常普遍; 只有一个核心可以访问任何一个寄存器,并且它们永远不会共享而不涉及内存.

将寄存器分配给变量的算法变得非常有效.

实际上,编译器现在非常善于将变量分配给寄存器,它们通常在优化方面比任何人都做得更好.他们当然知道你最常使用哪些,而不告诉他们.如果编译器需要遵守您的手动register提示,那么编译器(即不是标准或程序员)会产生这些优化会更复杂.编译器断然忽略它们变得越来越普遍.到C++存在时,它已经过时了.它包含在标准中以便向后兼容,以使C++尽可能接近C的正确超集.编译器遵守提示的要求以及因此强制执行提示可以遵守的条件的要求被削弱了因此.今天,存储类本身已被弃用.

因此,即使它仍然今天的情况(和将要等到电脑甚至不具有寄存器),你不能在逻辑上有一个CPU寄存器参考,期望的是,register 存储类将荣幸被这么长时间过去了,它标准要求编译器要求您在使用它时合乎逻辑是不合理的.


Nit:我认为你的意思是C++是C的超集(从技术上来说它不是,尽管很多工作已经用于最小化不兼容性)
推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有