volatile 限定符
为什么使用volatile
根据CPP之父的说法:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
直接处理硬件的程序往往会包含这样的数据元素,这些元素可能会被程序之外的过程控制,因此对象的值很有可能会被程序之外修改,这时应该把对象声明为volatile。
声明为volatile的变量在编译器访问它时,编译器就不再对它做任何优化,从而提供稳定的地址访问。例如,系统总是会重新从内存中读取该数据,即便在它前面的指令中已经都读取过数据并存储在寄存器中。
一般来说,volatile用在以下几个方面:
- 中断服务程序中修改的的供其它程序检测的变量需要加volatile;
- 多任务环境下多任务共同分享的标志需要加volatile;
- 存储器映射的硬件寄存器需要加volatile(因为每次的读写意义不同);
通常情况下,是在多线程共享变量时,一个线程改变变量,使得该变量对其它线程visible。也可以避免当两个线程用到同一个变量时,一个线程使用寄存器中的变量,一个线程使用内存中的变量;
volatile指针
volatile与const之间没有什么影响,一个变量可以既是volatile的也是const。
1 | volatile int v; // v是一个volatile的int |
同const,只能将一个volatile的对象赋予一个指向volatile的指针。
拷贝构造
与const不同,我们不能使用合成的拷贝/移动构造函数以及赋值运算符来初始化一个volatile对象。因为合成的成员接受的实参是一个非volatile的常量引用,我们不能将一个非volatile引用绑定到volatile对象上。
因此我们必须自定义拷贝或者赋值操作:
1 | class Foo{ |