• C语言中volatile关键字的作用


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

    int i = 10;
    int main(void){
        int a, b;
        a = i;
        ...//伪代码,里面不含有对 a 、 b 以及 i的操作
        b = i;
        if(a == b){
            printf("a = b");
        }
        else {
            printf("a != b");
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如上代码,如果选择编译器优化,可能会被编译成如下代码(当然不是在C语言层面上优化,而是在汇编过程优化,只是使用C程序举例):

    int i = 10;
    int main(void){
        int a, b;
        a = i;
        ...//伪代码,里面不含有对 a 、 b 以及 i的操作
        b = i;
        printf("a = b");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    因为在仅仅从main主函数来看,a == b是必然的,那么在什么情况,a 和 b不是必然相等呢?

    1. i 是其他子线程与主线程共享的全局变量,其他子线程有可能修改 i 值;

    2. i 是中断函数与主函数共享的全局变量,中断函数有可能修改 i 值;

    3. i 属于硬件寄存器,CPU可能通过硬件直接改变 i 的值(例如寄存器的标志位)

    volatile 常见的几个面试题

    1、一个参数既可以是const还可以是volatile吗?

    可以,例如只读的状态寄存器。它是 volatile 因为它可能被意想不到地改变。它是 const 因为 程序不应该试图去修改它。

    2、一个指针可以是 volatile 吗?

    可以,当一个中服务子程序修改一个指向一个 buffer 的指针时。

    3、下面的函数有什么错误:

    int square(volatile int *ptr) 
    { 
        return *ptr * *ptr; 
    } 
    
    • 1
    • 2
    • 3
    • 4

    这段代码的目的是用来返指针* ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

      int square(volatile int *ptr)  
        { 
             int a,b; 
             a = *ptr; 
             b = *ptr; 
             return a * b; 
         } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    long square(volatile int *ptr)  
    { 
        int a; 
        a = *ptr; 
        return a * a; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    总结:

    volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如 果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。所以遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问


    谢谢大佬们的文章,转自: https://blog.csdn.net/weixin_38815998/article/details/102840096?spm=1001.2101.3001.6650.4&depth_1-utm_relevant_index=8

    https://juyou.blog.csdn.net/article/details/54024070?spm=1001.2101.3001.6650.1&depth_1-utm_relevant_index=2

  • 相关阅读:
    C 语言超全练习题(一): 初识C语言
    软件工程(十八) 行为型设计模式(四)
    专利申请被驳回,如何专利复审?
    基于javaweb的宿舍管理系统(idea+servlet+jsp+jdbc)
    论文阅读之《Quasi-Unsupervised Color Constancy 》
    【力扣周赛】来自VIP的原题压制:2406.将区间分为最少组数,内含福利!
    spring5.0源码解析 Aop 01
    freeswitch-1.10.7性能测试
    《PyTorch 深度学习实战》- 第一章 深度学习回顾和PyTorch简介
    军训场KL
  • 原文地址:https://blog.csdn.net/qq_44333320/article/details/125631490