在c++中,volatile用与修饰容易变动的变量,通常用于多线程的标志,编译器会存在代码优化,假如在同一个大括号中没有修改这么一个参数,那么编译器很可能在读取这个值的时候使用的是快取的方法,即将这个值在这段括号中如果没有改变的话,直接拷贝一份放在内存中,每次都从这里取而不是去寄存器取值,而对于多线程的程序,由于代码没在同一个括号下面,编译器在编译的时候可能无法识别,误以为这个值并没有改变,那么将会产生意外的结果,
简单地说就是防止编译器对代码进行优化.比如如下程序:
1
2
3
4
|
XBYTE[2]=0x55; XBYTE[2]=0x56; XBYTE[2]=0x57; XBYTE[2]=0x58; |
对外部硬件而言,上述四条语句分别表示不同的操作,会产生四种不同的动作,但是编译器却会对上述四条语句进行优化,认为只有XBYTE[2]=0x58(即忽略前三条语句,只产生一条机器代码)。如果键入volatile,则编译器会逐一的进行编译并产生相应的机器代码(产生四条代码).
1
2
3
4
5
6
7
|
int square( volatile int *ptr ) { int a,b; a = *ptr; b = *ptr; return a * b; } |
由于*ptr的值可能在两次取值语句之间发生改变,因此a和b可能是不同的。结果,这段代码可能返回的不是你所期望的平方值!正确的代码如下:
1
2
3
4
5
6
|
long square( volatile int *ptr ) { int a; a = *ptr; return a * a; } |
讲讲个人理解:
关键在于两个地方:
⒈编译器的优化(请高手帮我看看下面的理解)
在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后再取变量值时,就直接从寄存器中取值;
当变量值在本线程里改变时,会同时把变量的新值copy到该寄存器中,以便保持一致
所以引用百度的一段话来指导使用条件:
1. volatile对应的变量可能在你的程序本身不知道的情况下发生改变
2. 比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量
3. 你自己的程序,是无法判定何时这个变量会发生变化