导航

const和voliate定义同一变量

Posted on 2012-09-04 08:48  vivi_wind  阅读(2175)  评论(0编辑  收藏  举报

http://topic.csdn.net/u/20071210/14/321d6ec5-f967-4afb-8d04-b335e6db7b34.html

 

不允许这里修改不代表不允许别处修改,再比如:
int i = 5;
const int* p = &i;
*p = 6; // 不可以;
i = 7; // 完全可以,而且那个“const”的“*p”也跟着变成了7。

const和volatile放在一起的意义在于:
(1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心;
(2)另一个程序段则完全有可能修改,因此编译器最好不要做太激进的优化。

“const”含义是“请做为常量使用”,而并非“放心吧,那肯定是个常量”。
“volatile”的含义是“请不要做没谱的优化,这个值可能变掉的”,而并非“你可以修改这个值”。
因此,它们本来就不是矛盾的啊。

需要明白“volatile”的含义并非是“non-const”。所以他们才可以放在一起。
在C++语言中,const没有反义词,如果一个变量没有const修饰,那它本身就是const的反义词,而并非加上volatile才是const的反义词。

 

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

C/C++ code
void f(constchar*str) { ... }


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

C/C++ code
void g(void) { char name[] ="Jim King"; f(name); ... }



另外一个例子在嵌入式系统中比较常见。很多嵌入式系统允许我们访问外部寄存器,该寄存器的地址可能是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
constvolatile unsigned char*STATUS_REG =0x0018; /* status register */