我正在为带有 Linux 环境的 ARM 编写程序。它不是一个低级程序,比如说应用程序级别
你能澄清一下有什么区别,
int iData;
对比
volatile int iData;
它有硬件特定的影响吗?
基本上,volatile
告诉编译器“这里的值可能会被这个程序外部的东西改变”。
当您(例如)处理硬件寄存器时,它很有用,这些寄存器经常“自行”改变,或者在向/从中断传递数据时。
关键是它告诉编译器 C 代码中变量的每次访问都必须生成对相关地址的“真实”访问,它不能被缓冲或保存在寄存器中,因为那样你就不会“看到”外部各方所做的更改。
对于常规的应用程序级代码,volatile
除非(当然)您正在与更低级别的东西进行交互,否则永远不需要。
volatile
关键字指定变量可以在任何时候不被程序修改。
如果我们谈论的是嵌入式,那么它可以是例如硬件状态寄存器。它包含的值可能会在任何不可预知的时刻被硬件修改。
这就是为什么,从编译器的角度来看,这意味着编译器被禁止对该变量应用优化,因为任何一种假设都是错误的,并且可能导致程序执行的不可预测的结果。
volatile means that variables value could be change any time by any external source. in GCC if we dont use volatile than it optimize the code which is sometimes gives unwanted behavior.
For example if we try to get real time from an external real time clock and if we don't use volatile there then what compiler do is it will always display the value which is stored in cpu register so it will not work the way we want. if we use volatile keyword there then every time it will read from the real time clock so it will serve our purpose....
But as u said you are not dealing with any low level hardware programming then i don't think you need to use volatile anywhere
thanks
一般来说, volatile 关键字旨在防止编译器对假定变量值不能“自行”更改的代码进行任何优化。
(来自维基百科)
现在,这是什么意思?
如果您有一个可能随时更改其内容的变量,通常是由于另一个线程对其进行操作,而您可能在主线程中引用此变量,那么您可能希望将其标记为volatile
. 这是因为通常变量的内容可以确定地“依赖”于使用变量的上下文的范围和性质。但是,如果您的范围或线程之外的代码也影响了变量,您的程序需要知道预期这一点并在必要时查询变量的真实内容,而不是正常情况。
当然,这是对正在发生的事情的简化,但我怀疑您是否需要volatile
在大多数编程任务中使用。
可以使用 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){
}
易失性抑制了编译器优化,编译器假定该值可以随时更改,即使没有显式代码修改它。易失性 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,编译器将知道
该值应始终从内存中读取
在以下示例中,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;
}
通过创建一个变量volatile
,每次访问该变量时,都会强制 CPU 从内存而不是缓存中获取它。这在多线程程序中很有帮助,其中许多线程可以重用缓存中变量的值。为了防止这种重用(在多线程程序中),使用了 volatile 关键字。这确保了任何变量read
或变量是稳定的(不缓存)write
volatile