register 和volatile

来源:互联网 发布:微信域名案 编辑:程序博客网 时间:2024/06/14 10:48


什么情况用寄存器变量:

       当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。register只是一个建议型关键字,能不能声名成功还取决于编译器(建议型的关键字还有c++中的 inline),若不幸没有请求成功,则变量变成一个普通的自动变量。是无法对一个register变量取地址的(因为寄存器变量多放在寄存器而非内存中,内存有地址,而寄存器是无地址的)。即便没有请求成寄存器变量,没有如愿的放入寄存器中,但是,依然不能对他取地址,因为他已经被声明为register了。


什么变量可以声明为寄存器变量:

.      只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量。


volatile和register       

就针对编译器而言,volatile所做的就是要求变量必须保存在内存中,而不允许被编译器进行优化放入缓存或者寄存器等等。
如果从作用上而言的话,我觉得它主要是用来防止脏数据的出现。

变量如果没有加入volatile修饰,可能会被编译器优化后写入缓存或者寄存器等等。在多线程情况下,并且多个线程对这个变量会进行频繁读写的话,那就会出现脏数据。即,如果一个线程修改了这个变量的值,但是变量新值还未及时更新到缓存或者寄存器时,另外一个线程一旦访问缓存或者寄存器,就会获取没有及时更新的脏数据。就有可能出现严重的错误!

register这个关键字的工作和volatile恰恰相反。
就是变量要求写入寄存器中。这种方式特别适用于不需要经常修改,但是会被频繁访问的变量,这样可以一定程度上提高访问效率。在ANSI C语言中,由于用了register,变量需要写入寄存器而不在内存中,所以利用&取址运算符是无法获取地址的,即,&取址运算符不能用于register修饰的变量。

当然由于现在编译器有很多,所以针对于register的编译方法也不尽相同了。
很多编译器其实不再对register关键词进行处理了,在编译时候编译器依然自行决定变量是否进行优化。一些C/C++编译器(例如Visual C++等),你依然可以对register修饰的变量进行取址。
很多新的编译器,不再像比较老的C编译器了,都已经可以很好的对变量是否写入寄存器进行很好的选择和优化,所以有些语言甚至去掉了register这个关键字。

C#语言中就没有register这个关键字了。

0 0