据我所知,register关键字将分配一个用于计算值的寄存器,每当我们对变量执行一些计算并且基本上不优化代码时,volatile关键字将从内存中读取值。那么,如果一个变量同时分配了这两个关键字,那么它是否意味着它本身就是易变的?我无法通过编写示例代码来理解这种行为。任何人都可以解释一下吗?
答案 0 :(得分:13)
在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;
答案 1 :(得分:6)
volatile
表示对象可能以编译器无法预测的方式发生更改,register
表示无法使用其地址。
当对象实际上是平台上的硬件寄存器时,两者的组合非常有意义。有些编译器(例如gcc)甚至有扩展来将这样的变量修复到特定的硬件寄存器。
其他一些代码可能会更改此类硬件寄存器,因此编译器可能不会假设当前值。在这种情况下,添加const
限定符甚至是有意义的。例如,gcc的扩展名
register uint32_t volatile const eax __asm__("eax");
你有一个工具可以随时检查eax
注册,但你无法偶然改变它。