首页 > 代码库 > volatile举列说明const

volatile举列说明const

  1.即使本程序中虽然不改变这种类型的值,但别的比如中断程序可能会改变这个值,加上volatile,编译器不优化,每次都重新访问这个值做判断

2.如

unsigned char flag = 1;

int main(int argc, char **argv) {
    reg_intr(XXX, intr_func);
    while(flag) {
        printf("hello\n");
    }
    return 0;
}

void intr_func(void)//中断函数

 {
    flag = 0;
}

3.“const”含义是“请做为常量使用”,而并非“放心吧,那肯定是个常量”。
“volatile”的含义是“请不要做没谱的优化,这个值可能变掉的”,而并非“你可以修改这个值”。

4.这个人说的一看就懂

另外一个例子在嵌入式系统中比较常见。很多嵌入式系统允许我们访问外部寄存器,该寄存器的地址可能是0x0018,该寄存器的最低位可能表示设备状态,1为忙碌,0为空闲。

C/C++ code
#define GET_REG_VALUE(reg)              (*reg)       /* get register value */
const unsigned char *STATUS_REG   = 0x0018;    /* status register */
const unsigned char  STATUS_BUSY = 0x01;        /* busy bit */
while (GET_REG_VALUE(STATUS_REG) & STATUS_BUSY); /* wait until free */
// do something to operate the device
...
 


这段代码很可能会死循环。因为编译器强奸民意的将地址0x0018处的值缓存起来,然后每次while的时候都从缓存中读取。虽然STATUS_REG的值是const unsigned char *,但这仅仅表示STATUS_REG寄存器是个只读寄存器,我们不能够在代码中去写这个寄存器,但并不表示这个寄存器是不能够改变的。硬件完成了它的任务之后,就会把状态设置成空闲,因此该寄存器的最后一位在我们循环的时候很可能已经发生了变化。因此在这样的地方,我们要禁止编译器自作聪明的优化,方法如下:

C/C++ code
 const volatile unsigned char *STATUS_REG   = 0x0018;    /* status register */

5.

只读表示编译器不允许代码修改变量。但并不表示这个变量在其它地方不能够被修改(不能被修改岂不就成了常量?)。比如:

C/C++ code
 
?
1
2
3
4
void f(const char *str)
{
...
}


在上面的程序中,str所指向的内存区域就是只读的,但这个只读性只在函数f内部,出了f,这块内存完全有可能是能够被修改的。

 
 
C/C++ code
 
?
1
2
3
4
5
6
void g(void)
{
    char name[] = "Jim King";
    f(name);
...
}

volatile举列说明const