volatile

volatile 告诉编译器定义的变量是随时可能发生变化的,每次使用它的时候必须从变量的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。  而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。

1.一个参数可以是const还可以是volatile吗?

可以,例如只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 

2.一个指针可以是volatile 吗

可以,如当一个中服务子程序修该一个指向一个buffer的指针时。

3.int square(volatile int *ptr) 

    return *ptr * *ptr; 

} 这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr) 

    int a,b; 
    a = *ptr; 
    b = *ptr; 
    return a * b; 
} 由于*ptr的值可能被意想不到地改变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr) 

    int a; 
    a = *ptr; 
    return a * a; 

3.嵌入式编程中的volatile

a.告诉编译器不能做任何优化
比如要往某一地址送两指令:
int *ip =...; //设备地址 
*ip = 1; //第一个指令 
*ip = 2; //第二个指令 
//以上程序compiler可能做优化而成: 
int *ip = ...; 
*ip = 2; 
结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意:
volatile int *ip = ...; 
*ip = 1; 
*ip = 2; 
即使你要compiler做优化,它也不会把两次付值语句间化为一。它只能做其它的优化。这对device driver程序员很有用。

b.表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。

volatile char a;   
a=0; 
while(!a) { 
    //do some things;   
}   
doother(); 
//如果没有 volatile doother()不会被执行


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章