您的位置:首页 > 其它

关键字volatile有什么含意 并给出三个不同的例子

2016-07-24 19:36 375 查看
volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值,即不是从寄存器里取备份值,而是去该地址内存存储的值.

简单地说就是防止编译器对代码进行优化.比如如下程序:

XBYTE[2]=0x55;

XBYTE[2]=0x56;

XBYTE[2]=0x57;

XBYTE[2]=0x58;

对外部硬件而言,上述四条语句分别表示不同的操作,会产生四种不同的动作,但是编译器却会对上述四条语句进行优化,认为只有XBYTE[2]=0x58(即忽略前三条语句,只产生一条机器代码)。如果键入volatile,编译器会逐一的进行编译并产生相应的机器代码(产生四条代码).下面是volatile变量的几个例子:

1) 并行设备的硬件寄存器(如:状态寄存器);

2) 一个中断服务子程序中会访问到的非自动变量;

3) 多线程应用中被几个任务共享的变量;

这是区分C程序员和嵌入式系统程序员的最基本的问题:嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所有这些都要求使用volatile变量。不懂得volatile内容将会带来灾难。

1) 一个参数既可以是const还可以是volatile吗?解释为什么。

答案:

1) 是的。一个例子是只读的状态寄存器(计算机系统的核心部件——运算器的一部分,状态寄存器用来存放两类信息:一类是体现当前指令执行结果的各种状态信息(条件码),如有无进位(CF位)等;另一类是存放控制信息(PSW:程序状态字寄存器),如允许中断(IF位)等)。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。没问题,const和volatile这两个类型限定符不矛盾。const表示(运行时)常量语义:被const修饰的对象在所在的作用域无法进行修改操作,编译器对于试图直接修改const对象的表达式会产生编译错误。volatile表示“易变的”,即在运行期对象可能在当前程序上下文的控制流以外被修改(例如多线程中被其它线程修改;对象所在的存储器可能被多个硬件设备随机修改等情况):被volatile修饰的对象,编译器不会对这个对象的操作进行优化。一个对象可以同时被const和volatile修饰,表明这个对象体现常量语义,但同时可能被当前对象所在程序上下文意外的情况修改。

2) 一个指针可以是volatile吗?解释为什么。

是的。尽管这并不很常见。一个例子是当一个中断服务子程序修该一个指向一个buffer的指针时。

3) 下面的函数有什么错误:

intsquare(volatile int *ptr)

{

  return *ptr *  *ptr;

}

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

intsquare(volatile int *ptr)

{

inta,b;

a =*ptr;

b =*ptr;

returna * b;

}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

longsquare(volatile int *ptr)

{

int a;

a =*ptr;

returna * a;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: