C语言中volatile的作用和使用方法

volatile关键字在编程中用于防止编译器优化,确保多线程环境下变量的可见性和同步。当变量可能被其他线程或外部硬件设备修改时,使用volatile可以保证每次读写都直接操作内存,避免编译器优化导致的问题。例如,在C语言的示例中,volatile防止编译器将变量缓存在寄存器,确保循环条件的正确检查。虽然使用volatile可能导致代码膨胀,但在多线程和硬件交互场景下是必要的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在程序设计中,尤其是在C语言、C++、C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化、多线程相关的特殊属性。

通常,volatile关键字用来阻止(伪)编译器认为的无法“被代码本身”改变的代码(变量/对象)进行优化

如在C语言中,volatile关键字可以用来提醒编译器它后面所定义的变量随时有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。编译器优化编译时会把不变的值放在寄存器,以供读取,标记volatile可以保证不被放入寄存器。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

举个栗子:

在这里例子中,代码将foo的值设置为0。然后开始不断地轮询它的值直到它变成255

static int foo;
 
void bar(void) {
    foo = 0;
 
    while (foo != 255)
         ;
}

一个执行优化的编译器会提示没有代码能修改foo的值,并假设它永远都只会是0.因此编译器将用类似下列的无限循环替换函数体:

void bar_optimized(void) {
    foo = 0;
 
    while (true)
         ;
}

但是,foo可能指向一个随时都能被计算机系统其他部分修改的地址,例如一个连接到中央处理器的设备的硬件寄存器,上面的代码永远检测不到这样的修改。如果不使用volatile关键字,编译器将假设当前程序是系统中唯一能改变这个值部分(这是到目前为止最广泛的一种情况)。

为了阻止编译器像上面那样优化代码,需要使用volatile关键字:

static volatile int foo;
 
void bar (void) {
    foo = 0;
 
    while (foo != 255)
        ;
}

这样修改以后循环条件就不会被优化掉,当值改变的时候系统将会检测到。

总结:

  优点:防止编译器对代码优化,变量值是直接从变量地址中读取和存储的。

  缺点: 这种使用过多会导致代码十分庞大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值