首页 > 其他分享 >102.volatile限定符

102.volatile限定符

时间:2023-07-04 13:11:56浏览次数:36  
标签:const 变量 int 对象 volatile 102 限定符 指针

☀警告

volatile的确切含义与机器有关,只能通过阅读编译器文档来理解。要想让使用了volatile的程序在移植到新机器或新编译器后仍然有效,通常需要对该程序进行某些改变。

直接处理硬件的程序常常包含这样的数据元素,它们的值由程序直接控制之外的过程控制。例如,程序可能包含一个由系统时钟定时更新的变量。当对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为volatile。关键字volatile告诉编译器不应对这样的对象进行优化。(比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。)

当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。

volatile定义变量的值是易变的,每次用到这个变量的值的时候都要去重新读取这个变量的值,而不是读寄存器内的备份。多线程中被几个任务共享的变量需要定义为volatile类型。

1.volatile指针

volatile限定符的用法和const很相似,它起到对类型额外修饰的作用:

volatile int display_register;  // 该int值可能发生改变
volatile Task *curr_task;  // curr task指向一个volatile对象 
volatile int iax [max_size];  // iax的每个元素都是volatile 
volatile Screen bitmapBuf;  // bitmapBuf的每个成员都是volatile

const和volatile限定符互相没什么影响,某种类型可能既是const的也是volatile的,此时它同时具有二者的属性。

就像一个类可以定义const成员函数一样,它也可以将成员函数定义成volatile的。 只有volatile的成员函数才能被volatile的对象调用。

const限定符和指针的相互作用,在volatile限定符和指针之间也存在类似的关系。我们可以声明volatile指针、指向volatile对象的指针以及指向volatile对象的volatile指针:

volatile int v; // v是一个volatile int 
int *volatile vip; // vip是一个volatile指针,它指向int
volatile int *ivp; // ivp是一个指针,它指向一个volatile int
volatile int *volatile vivp; // vivp是一个volatile指针,它指向一个volatile int 
int intv;
int *ip = &v;//错误:必须使用指向volatile的指针
ivp = &v; //正确:ivp是一个指向volatile的指针
vivp = &v;//正确:vivp是一个指向volatile的volatile指针
v = intv;//正确:可以把一个非volatile int赋给volatile int,但是不能把非volatile对象赋给一个volatile对象。
intv = v;//错误

●和const一样,我们只能将一个 volatile对象的地址(或者拷贝一个指向volatile类型的指针)赋给一个指向volatile的指针。同时,只有当某个引用是volatile的时,我们才能使用一个volatile对象初始化该引用。

●C++中一个有volatile标识符的类只能访问它接口的子集,一个由类的实现者控制的子集。用户只能用const_cast来获得对类型接口的完全访问。此外,volatile向const一样会从类传递到它的成员。

2.合成的拷贝对volatile对象无效

const和volatile的一个重要区别是我们不能使用合成的拷贝/移动构造函数及赋值运算符初始化volatile对象或从volatile对象赋值。合成的成员接受的形参类型是(非volatile)常量引用,显然我们不能把一个非volatile引用绑定到一个volatile对象上。

如果一个类希望拷贝、移动或赋值它的volatile对象,则该类必须自定义拷贝或移动操作。例如,我们可以将形参类型指定为const volatile引用,这样我们就能利用任意类型的Foo进行拷贝或赋值操作了:

class Foo
{
public:
	Foo(const volatile Foo&);//从一个volatile对象进行拷贝
	Foo& operator=(volatile const Foo&);//将一个volatile对象赋值给一个非volatile对象
	Foo& operator=(volatile const Foo&) volatile;//将一个volatile对象赋值给一个volatile对象
	//Foo类的剩余部分
};

尽管我们可以为volatile对象定义拷贝和赋值操作,但是一个更深层次的问题是拷贝volatile对象是否有意义呢?不同程序使用volatile的目的各不相同,对上述问题的同答与具体的使用目的密切相关。

3.多线程下的volatile

有些变量是用volatile关键字声明的。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用volatile声明,该关键字的作用是防止优化编译器把变量从内存装入CPU寄存器中。

如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。

volatile的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值。

4.保证变量在内存中的可见性

有数据一致性的隐患

5.禁止编译器做过度优化


6.禁止指令重排






voltile具有内存屏障的功能



参考资料来源:

阿秀、C++Primer、在划水里划水

标签:const,变量,int,对象,volatile,102,限定符,指针
From: https://www.cnblogs.com/codemagiciant/p/17525492.html

相关文章

  • 39.volatile、mutable和explicit关键字的用法
    39.volatile、mutable和explicit关键字的用法1.volatile☀警告volatile的确切含义与机器有关,只能通过阅读编译器文档来理解。要想让使用了volatile的程序在移植到新机器或新编译器后仍然有效,通常需要对该程序进行某些改变。直接处理硬件的程序常常包含这样的数据元素,它们的值......
  • P1025 [NOIP2001 提高组] 数的划分
    https://www.luogu.com.cn/problem/P1025#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>usingnamespacestd;constintN=10;intn,k;intans;intst[N];voiddfs(intlast,intleft,intstep)//利用last来......
  • volatile是如何保证有序性的?
    为什么需要保证有序性?有如下代码,在inti=a;执行了的情况下,i的值最终会为几?publicclassNoVolatileExample{inta=0;booleanflag=false;publicvoidwriter(){a=1;flag=true;}publicvoidreader(){if(flag......
  • 游戏服务器被攻击怎么办?绍兴高防服务器租用203.135.102.x
    游戏服务器遭受攻击的原因可能有很多。攻击者可能会利用多种方式来入侵服务器,如通过计算机病毒、木马程序、蠕虫程序和社交工程等方式。这些攻击可以让服务器瘫痪,造成用户数据丢失、业务中断,甚至影响到公司的声誉。今天我就来和大家说原因和解决方法一、竞争对手来攻击你的服务器,让......
  • CF Gym 102994 Travel Dream
    题意求一张带权无向图中最大的\(k\)元简单环,无解输出impossible。\(1\len,m\le300,k\le10\)。注意\(k\)的范围题解\(k\)很小,存在简单办法对小环小链进行预处理,考虑折半。首先考虑怎么求长度小于等于4的链。长度为\(1,2\)的链可以直接枚举,长度为\(3\)的链......
  • volatile关键字的作用
    Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。volatile变量具备两种特性,volatile变量不会被缓存在寄存器或者对其他的处理不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。变量可见性:其一是保证该变量对所有线程可见......
  • (2023.6.28)ls1028相关
    1.核心板升级为V1.3版,解决MDIO总线不稳定问题?现象是什么2.PHY芯片由AR8031和QCA8075更换为YT8521和YT86143.因核心板加密芯片A1006L原厂设计BUG,在高温和低温环境下可能会出现加密芯片不能正常工作,加密失败导致核心板不能启动。更换核心板加密为AL10074.外部的两个phy的md......
  • volatile 关键字
    原文链接:https://liamw.cn/albums/csharp-dotnet/10-understand-the-volatile-keyword要理解C#中的 volatile 关键字,就要先知道编译器背后的一个基本优化原理。比如对于下面这段代码: publicclassExample{publicintx;publicvoidDoWork(){x......
  • 刚装完的数据库报错 ORA-01102 ORA-1102 signalled during....
        昨天刚装完的一个数据库在启动的时候,报错ORA-01102,而且安装的时候也没有看到哪里有报错信息,一路都比较顺利,而且这也是第一次我碰到这个问题,当时我首先就检查了alert日志文件,并把相关的错误信息在metalink上查看过了,经过分析后判断是由于进程间通信被争用导致,以下是我处......
  • dbca -silent -responsefile 建库由于tmpfs太小报错ORA-27102: out of memory
    错误信息:[oracle@db01~]$dbca-silent-responsefiledbca.rspCopyingdatabasefiles1%complete2%complete4%complete12%complete100%completeLookatthelogfile"/DBSoft/oracle/cfgtoollogs/dbca/woo/woo.log"forfurtherdetails.[oracle@db01......