文章目录

  • 前言
  • 1、有关volatile的故事
  • 2、顺带一提的const
  • 3、__IO、__O、__I的缘起

前言

  在阅读意法官方给的STM32固件库的工程中的时候偶然看见了_IO修饰的变量然后发现其实这是STM32固件库中的宏定义关键字,其实它是volatile关键字,本篇博客用于整理和其相关资料。

#define     __I     volatile const             /*!< defines 'read only' permissions      */
#define     __O     volatile                  /*!< defines 'write only' permissions     */
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */

1、有关volatile的故事

  volatile 影响编译器编译的结果,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错。

一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

例如:

volatile int i=10;
int j = i;
...
int k = i;

  volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。而如果没有volatile关键字编译器的做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。


  以下内容来自https://blog.csdn.net/qq_27312943/article/details/51273064我认为对理解volatile用途有帮助就分享给大家。

  我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到 volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是真的懂得volatile完全的重要性。
  1) 一个参数既可以是const还可以是volatile吗?解释为什么。
  2) 一个指针可以是volatile吗?解释为什么。
  3) 下面的函数有什么错误:

int square(volatile int *ptr)
{   return *ptr * *ptr;
}

答:
  1) 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
  2) 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
  3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)
{   int a,b;   a = *ptr;  b = *ptr;  return a * b;
}

  由于*ptr的值可能被意想不到地该变,因此ab可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)
{   int a;   a = *ptr;  return a * a;
}

2、顺带一提的const

  const是只读变量,即变量保存在只读静态存储区。编译时,如何尝试修改只读变量,则编译器提示出错,就能防止误修改(这个关键字就不多说了,不了解的可以戳这里)。


3、__IO、__O、__I的缘起

  前面介绍了 volatile 和 const 的用法,不知道大家了解了没?了解了后,下面的讲解就更加容易了:
  __I :输入口。既然是输入,那么寄存器的值就随时会外部修改,那就不能进行优化,每次都要重新从寄存器中读取。也不能写,即只读,不然就不是输入而是输出了。
  __O :输出口,也不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那一次输出,假如外部在两次输出中间修改了值,那就影响输出
  __IO:输入输出口,同上

【C语言】关键字volatile之有关__IO、__O、__I的故事相关推荐

  1. C语言关键字--volatile(不稳定的,反复无常的)

    volatile是C语言中的一种类型修饰符,用它声明的变量表示可以被某些编译器未知的因素更改,比如操作系统.硬件或其它线程等.遇到它声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特 ...

  2. c语言 关键字volatile和register

    volatile volatile是防止编译器优化,如果是高频繁的变量编译器会自动将变量放到寄存器中,但是有的变量需要实时更新不能间断,放到寄存器中会隔一段时间再去获取变量,导致变量的值不在准确 re ...

  3. 【译】volatile C语言关键字,如何使用?

    原文 概要 许多程序员无法正确的理解C语言关键字volatile.这并不奇怪,大多数C原因书籍不过一两句一带而过.本文将告诉你如何正确使用它. 在C/C++嵌入式代码中,你是否经历过下面的情况: 代码 ...

  4. amp quot memory c语言,c volatile 关键字

    C++ volatile 关键字- 简书 2017年1月1日 - 注意:本文中代码均使用Qt 开发编译环境volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改. ...

  5. C语言再学习 -- 关键字volatile

    上周确实事情挺多的,年会.公司聚餐,一到过年就有忙不完的事分心.还好C语言再学习总结的已经差不多了,年前也不展开别的了,接下来这十几天.总结几篇典型的面试题吧. 言归正传,接下来看看关键字 volat ...

  6. C语言中的关键字“ volatile”的用法(摘)

    C语言中的关键字" volatile"的用法(摘) volatile 这个ANSI C 关键字在经典的C 教程中很少提及,高层编程的人也可能永远都 不会用到,但是作为嵌入式开发者来 ...

  7. C语言:关键字volatile详解!

    一.volatile 介绍 参看:volatile详解 参看:C Language Keywords Indicates that a variable can be changed by a bac ...

  8. C语言面试题小练——第10天:宏定义一年的秒数、变量定义练习、关键字volatile有什么含意

    文章目录 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) 2. 用变量a给出下面的定义 3. 关键字volatile有什么含意?并给出三个不同的例子. 1. 用 ...

  9. C语言基础 — 关键字volatile有什么含意? 三个不同的例子。

    关键字volatile有什么含意? 并给出三个不同的例子. 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了.精确地说就是,优化器在用到这个变量 ...

最新文章

  1. ASP.NET Core 模型验证的一个小小坑
  2. quick sort
  3. 发布订阅之direct
  4. 【Elasticsearch】 Elasticsearch slop管理间隔字符查数据
  5. Docker-创建支持ssh服务的镜像
  6. onContextItemSelected 与 onMenuItemSelected 的那些事
  7. MySQL触发器自动更新memcache[转]
  8. 亚马逊云科技携海信集团打造全球服务实践案例标杆
  9. 小红伞 for 2003
  10. CPU GPU设计工作原理(转载)
  11. android黑色半透明dialog背景,Dialog背景半透明
  12. android 传感器使用与开发---陀螺仪传感器
  13. PAT Basic 1068 万绿丛中一点红
  14. VTK:生成网格(附完整源码)
  15. Some weights of the model checkpoint at bert_pretrain were not used when initializing BertModel
  16. 关于input在苹果和安卓手机上调用相机和相册的问题
  17. iOS性能优化-UI卡顿检测
  18. 海康摄像头SDK二次开发错误问题解决方案(一):2. 错误号64:NET_DVR_LOADPLAYERSDKFAILED 64 载入当前目录下 Player Sdk 出错
  19. 镁客网每周硬科技领域投融资汇总(2.25-3.3),区块链领域共发生7起融资事件...
  20. C语言过时了?扯淡!

热门文章

  1. php7 mysql json 小程序_微信小程序JSON数组递交PHP服务端解析处理
  2. mac win10 mysql_Mac装双系统Win10,安装MySQL遇到的问题
  3. Python Pandas导出Hbase数据到dataframe
  4. python借助missingno可视化分析缺失值
  5. 解决Flink案例DataStream中使用keyBy(0),keyBy弃用的问题
  6. android开发卡死代码,Android Studio编译卡死(示例代码)
  7. mysql如何优化where子句
  8. BZOJ.4909.[SDOI2017]龙与地下城(正态分布 中心极限定理 FFT Simpson积分)
  9. hibernate 各历史版本下载 spring各历史版本下载
  10. ADO.NET常用对象详解之:DataAdapter对象