C中的易失性关键字

时间:2013-04-17 10:04:49

标签: c volatile

我正在为Linux环境编写ARM程序。它不是一个低级别的程序,比如app level

你能说清楚我之间的区别吗,

int iData;

VS

volatile int iData;

它是否具有特定于硬件的影响?

7 个答案:

答案 0 :(得分:4)

基本上,volatile告诉编译器“这里的值可能会被这个程序外部的东西改变”。

当您(例如)处理硬件寄存器时,它通常会“自行更改”,或者在向中断传递数据时使用它。

关键是它告诉编译器C代码中变量的每次访问都必须生成对相关地址的“实际”访问权限,它不能被缓冲或保存在寄存器中,因为那样你就不会“看”外部各方所做的改变。

对于常规的应用程序级代码,除非(当然)与较低级别的内容进行交互,否则永远不需要volatile

答案 1 :(得分:3)

volatile关键字指定可以随时修改变量而不是程序。

如果我们谈论嵌入式,那么它可以是例如硬件状态寄存器。在任何不可预测的时刻,硬件都可以修改它包含的值。

这就是为什么从编译器的角度来看,这意味着编译器禁止对此变量应用优化,因为任何类型的假设都是错误的并且可能导致程序执行的不可预测的结果

答案 2 :(得分:0)

  

一般来说,volatile关键字旨在防止编译器对代码应用任何优化,这些代码假定变量值不能“自行”更改。

(来自维基百科)

现在,这是什么意思?

如果你有一个可以随时更改其内容的变量,通常是由于另一个线程在你可能在主线程中引用这个变量而对它进行操作,那么你可能希望将其标记为{{1} }。这是因为通常变量的内容可以“确定地”依赖于使用变量的上下文的范围和性质。但是,如果范围或线程之外的代码也影响变量,那么程序需要知道这一点,并在必要时查询变量的真实内容,超出正常范围。

这是对正在发生的事情的简化,当然,但我怀疑你需要在大多数编程任务中使用volatile

答案 3 :(得分:0)

在以下示例中,未明确修改global_data。因此,当优化完成时,编译器会认为,无论如何都不会进行修改。所以它为global_data指定0.并使用0,使用global_data

但实际上global_data通过其他一些过程/方法(比如通过ptrace)进行了更新。通过使用volatile,您可以强制它始终从内存中读取。这样你就可以获得最新的结果。

#include <stdio.h>    
volatile int global_data = 0;

int main()
{

FILE *fp = NULL;
int data = 0;    
printf("\n Address of global_data:%x \n", &global_data);

        while(1)
        {
              if(global_data == 0)
                {                    
                      continue;
                }
                else if(global_data == 2)
                {
                        ;
                        break;
                }
        }    

return 0;
}

答案 4 :(得分:0)

通过创建变量volatile,每次访问变量时,都会强制CPU从内存而不是从缓存中获取它。这在多线程程序中很有用,因为许多线程可以在缓存中重用变量的值。为了防止这种重用(在多线程程序中),使用volatile关键字。这可以确保readwritevolatile变量的任何内容都是稳定的(不会缓存)

答案 5 :(得分:0)

可以使用volatile关键字,

当对象是内存映射的io端口时。

An 8 bit memory mapped io port at physical address 0x15 can be declared as
char const ptr = (char *) 0x15;
Suppose that we want to change the value at that port at periodic intervals. 
*ptr = 0 ;
while(*ptr){
*ptr = 4;//Setting a value
*ptr = 0; // Clearing after setting
}
 It may get optimized as
*ptr = 0 ;
while(0){
}

Volatile压缩编译器优化,编译器假定tha值可以 即使没有明确的代码修改它,也可以随时更改。 Volatile char * const ptr =(volatile char *)0x15;

当对象被ISR修改时使用。

有时,ISR可能会改变主线代码中使用的值

static int num;
void interrupt(void){ 
++num;
}
int main(){
int val;
val = num;
while(val != num)
val = num;
return val;
}

这里编译器对while语句做了一些优化。编译器
以这样的方式产生代码,使得num的值总是从cpu中读取 注册而不是从内存中读取。while语句将始终为
假。但在实际情况下,num的值可能会在ISR中发生变化而且会发生变化 反映在内存中。如果变量声明为volatile,编译器将知道 该值应始终从内存中读取

答案 6 :(得分:0)

volatile意味着任何外部源都可以随时更改变量值。在GCC,如果我们不使用volatile而不是优化代码,这有时会产生不必要的行为。

例如,如果我们试图从外部实时时钟获取实时时间,并且如果我们不使用volatile那么编译器会做什么,它将始终显示存储在cpu寄存器中的值,因此它将无法工作我们想要的方式。如果我们在那里使用volatile关键字,那么每次它都会从实时时钟读取,这样就可以满足我们的目的......

但正如你所说,你没有处理任何低级硬件编程,那么我认为你不需要在任何地方使用volatile

感谢