Chinaunix首页 | 论坛 | 博客
  • 博客访问: 807149
  • 博文数量: 157
  • 博客积分: 542
  • 博客等级: 中士
  • 技术积分: 1696
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-21 20:21
文章分类
文章存档

2017年(1)

2016年(2)

2015年(6)

2014年(42)

2013年(77)

2012年(19)

2011年(10)

分类: C/C++

2011-11-24 22:00:43

  
    看过许多的关于C的笔试题或者面试题,里面都会有提到volatile这个关键字,很多面试的人认为这是区分一般C程序员和嵌入式程序员的一把标尺。其实个人认为volatile 对于一个嵌入式程序员,并不是一个硬性指标。比如本人是做上层路由协议开发,但并没有怎么接触volatile,陌生。但学习C的我们至少应该是抱着越来越的心态: 越来越了解它,越来越多的运用它。
   
    volatile 原意:名词为 挥发物,形容词为 易变的 (来自google翻译)。
   
    一般遇到这个关键词修饰的变量,编译器将对这段代码的访问不进行优化。
    编译器的优化,了解的不多。说说我了解到的一点:由于一般访问CPU寄存器比去访问内存要快一点,所以优化编译器一般会把我们定义的变量缓存到寄存器中,以便加速后续的访问。而使用volatile则抑制了编译器的这种优化。
    比如下面这个例子。
   
   
  1. #include <stdio.h>

  2. int main (void)
  3. {
  4.   volatile int a = 1;
  5.   
  6.   int b = a;
  7.   
  8.   // 这里可以插入其他代码,以一种编译器未知的方式改变a的值。

  9.   int c = a;

  10.   return 1;
  11. }
    这里如果没有volatile修饰 a 那么这句 int b = a; 将是在编译器优化了a(即把a的值缓存到寄存器中)之后,直接从寄存器中读取a的值赋给b, 而不是现在有volatile修饰的需要直接根据a的地址到内存中读取a的值。
    代码中的注释告诉我们,如果我们在这里添加一段代码,其用意是修改a的值而不让编译器知道。(这里修改a的值的一种方法是可以用一段汇编代码,可惜我对汇编不懂,是后续的目标)。这时如果a 并没有被volatile修饰,那么int c = a; c的值将是读取了被优化在寄存器中的a的值。而不是我们改变后的真实值。有volatile修饰则避免了这种情况,可以让c得到真实的a的值。
 
  对于volatile的作用应该不止上面这种,以前看到过另外一种作用的描述是这样的:
    不做常量合并、常量传播等优化,所以像下面的代码:
    volatile int i = 1; 
    if (i > 0) ...
    if的条件不会当作无条件真。 
    上面这种代码可以理解,但是描述中的常量合并,常量传播不了解是指什么样的情况。
    google了一下可能是这样理解的:
    常量合并,是指编译器把一个常量值const int a = 1;直接把a保存在符号表里而不是给a分配空间,以后在需要a的时候直接读取符号表里的1来替换a。
    不知道是不是这种理解的,求高手讲解,求正解。
阅读(2234) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~