欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

C语言中volatile关键字的深入讲解

时间:2021-11-16 16:32:48|栏目:C代码|点击:

1. 什么是volatile关键字?

volatile用于声明一个变量,告诉编译器该变量值容易发生改变,在编译、读取、存储该变量的时候都不要做任何优化,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取存储数据,不做优化,在我们做嵌入式开发的时候,该关键字作用很大,因为有时变量地址有可能是系统的一个外设地址,他的值的变化并不在程序控制范围内,随时有可能变化,因此需要对他进行声明,每次读取或者存储直接对地址进行操作,而不经过其他中间商,下面我以一个例子来分析vilatile的作用:

2. GCC优化等级

在看例子前先了解一下GCC的优化概念,通常C语言的编译器使用的是GCC编译器,他有个以下几个等级的优化

  • -O0 :(默认):没有优化。
  • -O或-O1 :优化,但不要花费太多的时间。
  • -O2 :更积极地优化
  • -O3 :最积极地优化
  • -Ofast :最高级的优化
  • -Os : 优化代码大小
  • -Og :在尽量不干扰调试的情况下优化

开启不同的优化等级,程序编译后的结果就会发生一定的变化,而volatile就是在开启优化的情况下使用,保护变量不被优化

3.volatile声明变量测试

我们先写一段c程序

#include <stdio.h>
int main(void)
{
    volatile int i=0;
    i=1;
    i=2;
    i=3;
    printf("%d",i);
    return 0;
}

程序创建一个变量i,对i进行三次赋值,使用-O默认优化等级对代码进行编译,查看汇编结果,我们可以看到优化后,i=1和i=2被优化,没有生成之间汇编代码,直接取最后的值寻址赋值给i

当我们使用Volatile声明变量后

#include <stdio.h>
int main(void)
{
    volatile int i=0;
    i=1;
    i=2;
    i=3;
    printf("%d",i);
    return 0;
}

编译如下,可以看到变量i的每一个赋值都生成了汇编代码,没有被优化,每次赋值都重新寻址赋值

当我们使用volatile对一个映射到外部寄存器的地址进行声明后,如果像上面连续赋值来传数据给外部寄存器,使用volatile声明就可以保护指令不会被优化,程序实现正常功能,当然除了用于对寄存器的保护外,volatile有时也使用在多线程间共享变量的保护,如果不注意,编译器会认为变量只在当前函数使用而进行优化,在其他任务中进行的改变就变的无效;如果中断中改变一个状态变量给其他函数进行检测,如果没有加volatile进行声明,也可以会因为编译器的优化而无效,所以大家在以上三种情况下使用变量时可以结合编译器的优化等级考虑一下,是不是需要将变量声明一下volatile关键字!!!

总结

上一篇:C++实现LeetCode(61.旋转链表)

栏    目:C代码

下一篇:VScode + keil开发环境搭建安装使用过程

本文标题:C语言中volatile关键字的深入讲解

本文地址:http://www.codeinn.net/misctech/183726.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有