volatile的语法与const是一样的,但是volatile的意思是"在编译器认识的
范围外,这个数据可以被改变"
不知为何,环境正在改变数据,可能通过多任务、多线程或者中断处理,所以,
volatile告诉编译器不要擅自做出有关该数据的任何假定,优化期间也是如此
如果编译器说,我已经把数据读进寄存器,而且再没有与寄存器接触
一般情况下,编译器不需要再读这个数据,但如果数据是volatile修饰的,
编译器就不能作出这样的假定,因为这个数据可能被其他进程改变了
编译器必须重读这个数据而不是优化这个代码来消除通常情况下那些冗余的
读操作代码
就像建立const对象一样,程序员可以建立volatile对象,甚至还可以建立
const volatile对象,对象不能被客户程序员改变,但可通过外部的代理
程序改变
//: C08:Volatile.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// The volatile keyword
class Comm {
const volatile unsigned char byte;
volatile unsigned char flag;
enum { bufsize = 100 };
unsigned char buf[bufsize];
int index;
public:
Comm();
void isr() volatile;
char read(int index) const;
};
Comm::Comm() : index(0), byte(0), flag(0) {}
// Only a demo; won't actually work
// as an interrupt service routine:
void Comm::isr() volatile {
flag = 0;
buf[index++] = byte;
// Wrap to beginning of buffer:
if(index >= bufsize) index = 0;
}
char Comm::read(int index) const {
if(index < 0 || index >= bufsize)
return 0;
return buf[index];
}
int main() {
volatile Comm Port;
Port.isr(); // OK
//! Port.read(0); // Error, read() not volatile
} ///:~
就像const一样,我们可以对数据成员、成员函数和对象本身是有volatile
可以对volatile对象调用volatile成员函数
函数isr()不能像中断服务程序那样使用的原因是:在一个成员函数里,当前
对象(this)的地址必须被秘密地传递,而中断服务程序ISR一般不要参数
volatile的语法与const是一样的,所以对它们的讨论经常放在一起。
无输出