kun*_*l18 5 c c++ gcc g++ cpu-registers
我知道寄存器变量的概念和它的用例,但根据我的尝试,我脑子里几乎没有问题.
我不能在C中访问寄存器变量的地址,虽然我可以做C++!为什么?访问寄存器变量的寻址有什么问题吗?
假设我在C++中声明一个字符串变量作为寄存器,那么该变量将存储在哪里?在C++中声明非数字数据类型(如'string')的存储类是什么意义?
更新: 我认为C++允许我们获取寄存器变量的地址,因为我的程序中没有出现任何错误,如下所示:
#include<iostream>
#include<time.h>
using namespace std;
clock_t beg, en;
int main(){
int j, k=0;
beg=clock();
for(register int i=0;i<10000000;i++){
/*if(k==0){
cout<<&i<<endl; // if this code is uncommented, then C++ rejects the recommendation to make 'i' as register
k++;
}*/
}
en=clock();
cout<<en-beg<<endl;
cout<<&j<<endl<<&k;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我观察到的是,如果我将变量'i'作为寄存器并且不尝试使用'&i'来打印地址,那么C++接受推荐并将'i'存储在寄存器中,这可以从运行时间到for循环,如果'i'在寄存器中,则总是大约4-12 ms.但是,如果我尝试打印变量'i'的地址,那么虽然我没有得到任何错误,但C++拒绝推荐,这可以从执行循环的时间开始,如果我没有注册,总是超过25! !
所以,基本上我不能用C和C++中的存储类作为寄存器来获取变量的地址!为什么?
Ker*_* SB 17
C和C++是不同的语言.
在C中,您不能使用register存储来获取变量的地址.参看 C11 6.7.1/6:
具有存储类说明符的对象的标识符声明
register表明对对象的访问尽可能快.这些建议有效的程度是实施定义的.脚注:实施可以将任何
register声明简单地视为auto声明.[...]
在C++中,register是一个已弃用,无意义的关键字,它没有任何效果(除了可能充当编译器提示),并且声明的变量register仍然只具有自动存储.特别是,C++ 没有 "寄存器"存储类.(它只有继承自C 的存储类说明符.)C++ 11,7.1.1/3:
一个
register说明符是一种提示,如此声明的变量将被频繁使用的实现.[注意:提示可以忽略,在大多数实现中,如果采用变量的地址,它将被忽略.这个用途已被弃用[...]
用C甚至没有任何实际担保有关如何注册存储实现(实现可以自由治疗register为auto),但无论语言规则.
首先,我们来看看相关标准.C和C++总是有可能对此关键字有不同的含义.
C++ 2011第7.1.1节第2和第3段:
寄存器说明符应仅适用于块(6.3)中声明的变量名称或函数参数(8.4).它指定命名变量具有自动存储持续时间(3.7.3).在块作用域中声明没有存储类说明符或声明为函数参数的变量默认具有自动存储持续时间.
寄存器说明符是对实现的暗示,如此声明的变量将被大量使用.[注意:提示可以忽略,在大多数实现中,如果采用变量的地址,它将被忽略.不推荐使用此功能(参见D.2). - 结束说明]
C 2011第6.7.1节第6段和脚注121:
具有存储类说明符寄存器的对象的标识符声明表明对对象的访问尽可能快.这些建议有效的程度是实施定义的.)
实现可以将任何注册声明简单地视为自动声明.但是,无论是否实际使用了可寻址存储,使用存储类说明符寄存器声明的对象的任何部分的地址都无法显式(通过使用6.5.3.2中讨论的一元和运算符)或隐式计算(通过将数组名称转换为指针,如6.3.2.1中所述.因此,可以应用于使用存储类说明符寄存器声明的数组的唯一运算符是sizeof和_Alignof.
所以,让我们带走我们在这里学到的东西.
至于你在实践中看到的是什么:
register int,所以让我们超越它.register.在这种情况下,最好显示您的测试,因为测试本身可能存在问题.如果完整测试没问题,那么您的编译器肯定可能正在使用提示来生成更好的代码.for (int i=0; i<100; ++i){}和for (register int i=0; i<100; ++i) {}.| 归档时间: |
|
| 查看次数: |
9888 次 |
| 最近记录: |