0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关键字volatile是什么?volatile关键字对编译器优化的影响

Dp1040 来源:strongerHuang 2023-11-03 11:47 次阅读

在我的技术交流群里,经常会看到大家讨论一些“奇怪”的问题,其中有好几次我都发现,是他们全局变量“惹的祸”,问题就是全局变量被优化导致的。

可能初学者不太关心编译器优化的功能,但对于经验丰富的工程师来说,掌握代码优化是必备技能。

今天,我们讲述的话题就是关于代码优化中,关键字volatile在优化过程中起到的作用

关键字volatile是什么?

volatile是一个类型修饰符(type specifier)。

volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。

volatile变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

---来自百度百科

volatile的定义,应该在(读书)学习时都看过无数遍,但我相信绝大部分人都没有深刻理解其中含义

当你真正编程、开发项目之后,你就会进一步理解其中含义。

volatile关键字对编译器优化的影响

我们都知道编译器有优化代码的功能,我们常用的集成开发环境(Keil、 IAR等)都有优化选项。

473fd922-79e1-11ee-939d-92fbcf53809c.jpg

如果不使用关键字 volatile 申明变量,则编译器可能会对变量的访问并生成非预期的代码或删除预期的功能。

1、什么时候使用volatile?

常见使用volatile声明的情况:

访问内存映射外设。

在多个线程之间共享全局变量。

在中断例程或信号处理程序中访问全局变量。

比如,在STM32代码中:


#define __O volatile /*!< Defines 'write only' permissions */#define     __IO    volatile             /*!< Defines 'read / write' permissions */

浏览代码,你会发现,很多地方都使用了“__IO”,也就是volatile.

在跑系统的项目中,线程间共享的全局变量,建议都加上volatile关键字,这一点,很多人没有在意。

2、不用volatile时可能出现的问题

如果未将变量用volatile声明,则编译器会假定其值不能在其定义的范围之外进行修改。

因此,编译器可能会执行不需要的优化。这可以通过多种方式表现出来:

在轮询硬件时,代码可能会陷入循环。

多线程代码可能会表现出奇怪的行为。

优化可能会导致删除实现故意时序延迟的代码。

举个例子,这是我自己写一个延时函数:


void Delay(int Cnt){ int i;

while(Cnt--) { i++; for(i=0; i<10; i++);  }}

你在不同优化等级情况下,延时时间可能会不一样

同样的代码,你在Keil 和 IAR环境下编译出来的延时时间也可能不一样。

当然,更深入的理解就会牵涉到汇编代码,编译之后的汇编代码会比较直观的呈现差异。

本文转载自strongerHuang

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编译器
    +关注

    关注

    1

    文章

    1634

    浏览量

    49128
  • 关键字
    +关注

    关注

    0

    文章

    37

    浏览量

    6895
  • volatile
    +关注

    关注

    0

    文章

    45

    浏览量

    13024

原文标题:全局变量加/不加volatile的影响

文章出处:【微信号:玩点嵌入式,微信公众号:玩点嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Triton编译器优化技巧

    在现代计算环境中,编译器的性能对于软件的运行效率至关重要。Triton 编译器作为一个先进的编译器框架,提供了一系列的优化技术,以确保生成的代码既高效又适应不同的硬件架构。 1. 指令
    的头像 发表于 12-25 09:09 157次阅读

    Triton编译器与其他编译器的比较

    Triton编译器与其他编译器的比较主要体现在以下几个方面: 一、定位与目标 Triton编译器 : 定位:专注于深度学习中最核心、最耗时的张量运算的优化。 目标:提供一个高度抽象、灵
    的头像 发表于 12-24 17:25 297次阅读

    C语言关键字分别发生在哪个阶段

    的第一个阶段:预处理,对一些宏定义做替换。 第二个,const。 C语言中的 const 用于修饰只读变量,表示变量本身不能修改。 这个关键字会在编译的第二步起作用,也就是编译。强行修改一个只读变量,
    的头像 发表于 11-24 10:31 180次阅读

    Keil编译器优化方法

    我们都知道,代码是可以通过编译器优化的,有的时候,为了提高运行速度或者减少代码尺寸,会开启优化选项。
    的头像 发表于 10-23 16:35 544次阅读
    Keil<b class='flag-5'>编译器</b><b class='flag-5'>优化</b>方法

    C语言关键字--typedef

    C语言关键字使用方法学习指南!
    的头像 发表于 10-07 12:44 255次阅读

    使用边缘AI和Sitara处理进行关键字检测

    电子发烧友网站提供《使用边缘AI和Sitara处理进行关键字检测.pdf》资料免费下载
    发表于 09-02 11:30 0次下载
    使用边缘AI和Sitara处理<b class='flag-5'>器</b>进行<b class='flag-5'>关键字</b>检测

    快速掌握C语言关键字

    C语言中的32个关键字你知道多少个呢?根据关键字的作用分为四类:数据类型关键字、控制语句关键字、存储类型关键字和其它
    的头像 发表于 07-06 08:04 349次阅读
    快速掌握C语言<b class='flag-5'>关键字</b>

    inline关键字优化导致此类函数被布局在flash内,怎么处理?

    == 0));} 由于uart.c多处调用这个函数,所以编译器自作聪明地把它编译成了非内联函数(意图是减少代码占用?),且elf能找到uart_ll_is_tx_idle标号
    发表于 06-21 12:03

    IDF4.2.1的编译器优化bug导致panic怎么处理?

    == 0) && (status.st_utx_out == 0));} 它是一个inline函数。我们都认为inline关键字,会告诉编译器内联此函数,于是它的代码
    发表于 06-21 10:55

    简单总结一下嵌入式C++中常见的错误形式

    对于 C++ 类,一些关键字只要写在 .h 中就好,cpp 中就不用再加上了,比如 virtual、static 等关键字,如果在 cpp 中多写,编译器会报错。
    的头像 发表于 02-23 09:40 504次阅读

    关键字搜索文件夹中某个TXT文件

    文件夹中随时创造TXT文件,如何及时选出刚创造的文件?或关键字搜索出需要的TXT文件?
    发表于 02-06 15:22

    谷歌搜索引擎优化的各个方面和步骤

    谷歌搜索引擎是最受欢迎和广泛使用的搜索引擎之一,为了使你的网站在谷歌上更好地排名并提高曝光度,你可以采取一些谷歌搜索引擎优化的步骤。 使用关键字研究工具,如Google AdWords关键字规划工具
    的头像 发表于 01-25 10:29 884次阅读

    在NVM和本地\"内存中定义数组(静态 /global /local)的\"关键字是什么?

    在 NVM 和本地\"内存中定义数组(静态 /global /local)的\"关键字是什么? 还有与 32 位对齐的关键字怎么样。
    发表于 01-25 07:52

    keil arm工程中结构体1节对齐如何实现

    在Keil Arm工程中,结构体的对齐方式可以通过使用特定的编译器指令或者关键字来实现。结构体的对齐方式会直接影响结构体变量在内存中的布局和对齐边界,从而对程序的性能和存储空间占用产生影响。 结构体
    的头像 发表于 01-05 14:40 3792次阅读

    探讨多线程编程中的volatile关键字应用

    有时候,我们可能需要在指针类型之间进行转换,而编译器会认为这是不安全的操作,从而导致编译错误。使用volatile关键字可以告知编译器,这个
    发表于 12-27 13:53 455次阅读