我知道register关键字将分配一个用于计算值的寄存器,而volatile关键字将在每次对变量执行某些计算时从内存中读取值,并且基本上不会优化代码.那么,如果一个变量同时分配了这两个关键字,那么它是否意味着它本身就是易变的?我无法通过编写示例代码来理解这种行为.任何人都能解释一下吗?
eca*_*mur 14
在C中,register存储类的行为与存储类完全相同auto,只是如果程序试图获取或使用对象的地址,则需要(根据5.1.1.3)发出诊断(6.5.3.2,6.7.1) ).使用register作为编译器的优化提示通常是没有意义的,因为足够聪明地利用对象的非存储质量的编译器当然足够聪明以跟踪可以声明哪些对象register; 相反,它应该被理解为代码质量检查,程序员不会通过获取对象的地址而无意中破坏优化机会.
换句话说,register从有效程序中删除关键字的所有实例对程序的语义没有影响 ; 它在这方面类似于static_assert.
该volatile类型限定符表示访问(读取和写入)的对象被认为是副作用,并且不能被优化掉.对于在定义的位置内存中不存在的对象(即具有register存储类的对象),这在性能测试中最有用:
start = time();
for (multiple loops)
register volatile int result = test_function();
stop = time();
elapsed = stop - start;
Run Code Online (Sandbox Code Playgroud)
volatile表示对象可能以编译器无法预测的方式更改,并且register意味着无法获取其地址.
当对象实际上是平台上的硬件寄存器时,两者的结合使得完美有意义.一些编译器(例如gcc)甚至具有将这样的变量修复到特定硬件寄存器的扩展.
其他一些代码可能会改变这样的硬件寄存器,因此编译器可能不会假设当前值.在这种情况下,添加const限定符甚至是有意义的.例如gcc的扩展名
register uint32_t volatile const eax __asm__("eax");
Run Code Online (Sandbox Code Playgroud)
你有一个随时检查eax注册表的工具,但是你无法意外地改变它.