这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 综合技术» 物联网技术» MDK中Const和volatile的使用

共1条 1/1 1 跳转至

MDK中Const和volatile的使用

助工
2008-04-28 11:55:05 打赏

更多关于RealView MDK的技术文章,请点击此处!

volatile的使用

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

有时在编译代码如果选用了优化级别-O2-O3,会产生某些问题。例如,可能在争夺硬件资源而陷入死循环,或者多个进程有些预想不到的行为。当遇到这些情况,你可能需要把有些变量定义为volatile

如果将一个变量定义为volatile则相当于告诉编译器该变量可能随时被改变,例如被操作系统或硬件所改变。因为带有限定符volatile的变量可以在任何时刻改变,该变量的物理地址可能被频繁地访问。这就意味着编译器不能对这些变量实现优化,例如,将变量缓存到寄存器避免访问内存。

相反,如果一个变量未被定义成volatile,则编译器认为该变量不能在应用程序之外改变。因此编译器可对这种变量实行优化。关键字volatile也不能滥用,可能会产生错误,比如如下例子:更多关于RealView MDK的技术文章,请点击此处!

C代码

通过编译器优化后的反汇编

int square(volatile int *ptr)
{
return *ptr * *ptr;
}

……

ldr r1, [r0]

ldr r0, [r0]

mul r0, r1, r0

……

这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器优化代码后将产生上表右边的代码。

由于*ptr的值可能被意想不到地该变,因此[r0]内存单元内的值可能是不同的。结果,这段代码可能返不是你所期望的平方值!

正确的代码应该如下:更多关于RealView MDK的技术文章,请点击此处!

C代码

通过编译器优化后的反汇编

int square(int *ptr)
{
return *ptr * *ptr;
}

……

ldr r1, [r0]

mul r0, r1, r1

……

当一个变量的值可能在应用程序不知道的情况下可能改变其值,为了避免优化带来的问题,需要将其定义为volatile类型。当有以下情况时需要定义为volatile类型的变量:

访问内存映射的外围设备。

在不同的进程之间共用全局变量。

在中断服务程序中访问全局变量。

const的使用

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。更多关于RealView MDK的技术文章,请点击此处!

即使不用关键字const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?原因如下:

关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。

合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

更多关于RealView MDK的技术文章,请点击此处!




关键词: Const volatile 使用 变量 代码

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]