C++中的volatile
volatile的本意是“易变的”,是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被寄存。例如:
volatile int i=10;int a = i;。。。//其他代码,并未明确告诉编译器,对i进行过操作int b = i;
volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。
#include <iostream>
using namespace std;int main(int argc,char* argv[])
{int i=10;int a=i;cout<<a<<endl;_asm{mov dword ptr [ebp-4],80}int b=i;cout<<b<<endl;
}
程序在VS2012环境下生成Release版本,输出结果是:
10
10
阅读以上程序,注意以下几个要点:
以上代码必须在Release模式下考查,因为只有Release模式下才会对程序代码进行优化,而这种优化在变量共享的环境下容易引发问题。
在语句b=i;之前,已经通过内联汇编代码修改了i的值,但是i的变化却没有反映到b中,如果i是一个被多个任务共享的变量,这种优化带来的错误很可能是致命的。
汇编代码[ebp-4]表示变量i的存储单元,因为ebp是扩展基址指针寄存器,存放函数所属栈的栈底地址,先入栈,占用4个字节。随着函数内申明的局部变量的增多,esp(栈顶指针寄存器)就会相应的减小,因为栈的生长方向由高地址向低地址生长。i为第一个变量,栈空间已被ebp入栈占用了4个字节,所以i的地址为ebp-i,[ebp-i]则表示变量i的存储单元。
加上volatile关键字
#include <stdio.h>void main(){volatile int i=10;int a = i;printf("i= %d/n",a);__asm {mov dword ptr [ebp-4], 20h}int b = i;printf("i= %d/n",b);}
在调试版本和release版本运行程序,输出都是:
i = 10
i = 32
这说明这个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的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr){int a;a = *ptr;return a * a;}```
相关文章:
C++中的volatile
volatile的本意是“易变的”,是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可…...

数学建模--一维插值法的多种插值方式的Python实现
目录 1.算法流程步骤 2.算法核心代码 3.算法效果展示 1.算法流程步骤 #算法的核心就是利用scipy中的interpolate来完成工作 #一共是5种一维插值算法形式: #插值方法:1.阶梯插值 2.线性插值 3.2阶样条插值 4.3阶样条插值 #"nearest"阶梯插值 #"zero&…...

爱校对:让法律、医疗、教育行业的文本更加无懈可击
在今天这个信息爆炸的世界里,文本准确性成了法律、医疗和教育这些严谨行业中一个不能忽视的要点。一个小错误可能造成严重的后果,甚至影响人们的生命和事业。这正是为什么更多的专业人士开始选择使用“爱校对”来确保他们的文档、研究和通讯无懈可击。 法…...

使用pip下载第三方软件包报错超时处理方法
报错如下: WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘ReadTimeoutEr ror(“HTTPSConnectionPool(host‘files.pythonhosted.org’, port443): Read timed out. (read timeout15)”)’: /p…...
计算古坐标——基于GPlates Web Service的坐标点重建
Gplates客户端和在线门户,pygplates和gplately是存在内在联系的应用,它们主要实现可视化,输入板块模型和化石点的现今坐标信息,在GPlates中可视化呈现,点位的坐标计算并不展现。而rgplates利用R语言提供了直接进行坐标…...

智安网络|加强软件供应链安全保障:共同抵御威胁的关键路径
在当今数字化时代,软件供应链安全成为了一个备受关注的话题。各行各业都依赖于软件产品和服务来支持其业务运营。然而,随着供应链的不断扩大和复杂化,软件供应链安全问题也日益突出。那么应该如何解决? 首先,软件供应…...

华为Mate 60系列发售,北斗卫星通信技术进一步深入大众消费市场
近日,华为Mate 60系列手机在没有举办发布会的情况下在官方商城突然上架开售,人气火爆。 值得一提的是,华为Mate60 Pro支持卫星通话,无地面网络时,也能拨打和接听卫星电话,还可自由编辑卫星消息。华为 Mate6…...

Grad-CAM,即梯度加权类激活映射 (Gradient-weighted Class Activation Mapping)
Grad-CAM,即梯度加权类激活映射 (Gradient-weighted Class Activation Mapping),是一种用于解释卷积神经网络决策的方法。它通过可视化模型对于给定输入的关注区域来提供洞察。 原理: Grad-CAM的关键思想是将输出类别的梯度(相对于特定卷积…...
程序发布——使用pyinstaller打包识别程序为exe可执行文件 详解
当我们使用python完成项目开发后,必然面对着如何将自己的程序分享给其他人使用,这就离不开程序的打包工作。对于大多数人而言,我们还是使用windows电脑居多,因此我们在大多数场景是需要将程序打包为exe的可执行文件。笔者将在本章节详细介绍使用pyinstaller进行打包的全过程…...

Docker 使用
简介 Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 Docker…...

电脑c盘变红满了怎么清理?4个方法轻松清理!
“我的电脑才用了不到一年,现在就已经满了!电脑c盘变红满了应该怎么清理呢?有什么方法能帮我清理的干净一点吗?希望大家给我出出主意。” 随着我们使用电脑时间的增多,电脑C盘可能会变得满满当当,这会不仅会…...

【UE 材质】实现角度渐变材质、棋盘纹理材质
目标 步骤 一、角度渐变材质 1. 首先通过“Mask”节点将"Texture Coordinate" 节点的R、G通道分离 2. 通过“RemapValueRange”节点将0~1范围映射到-1~1 可以看到此时R通道效果: G通道效果: 继续补充如下节点 二、棋盘纹理材质 原视频链接&…...

[深度学习]1. 深度学习知识点汇总
本文记录了我在学习深度学习的过程中遇到过的不懂的知识点,为了方便翻阅,故将其发表于此,随时更新,供大家参考。 深度学习常见知识点 1. 测试精度和训练精度 在深度学习中,测试精度和训练精度是两个重要的指标&#…...

鲁棒优化入门(6)—Matlab+Yalmip两阶段鲁棒优化通用编程指南(上)
0.引言 上一篇博客介绍了使用Yalmip工具箱求解单阶段鲁棒优化的方法。这篇文章将和大家一起继续研究如何使用Yalmip工具箱求解两阶段鲁棒优化(默认看到这篇博客时已经有一定的基础了,如果没有可以看看我专栏里的其他文章)。关于两阶段鲁棒优化与列与约束生成算法的原…...
golang通过gorm操作sqlite设置主键自增
在 Golang 中使用 GORM 操作 SQLite 数据库时,可以通过以下步骤设置主键自增: 首先,确保已经安装了 GORM 和 SQLite 的驱动程序。你可以使用以下命令安装它们: go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite导入所…...

基于Spring Boot的企业门户网站设计与实现(Java+spring boot+MySQL)
获取源码或者论文请私信博主 演示视频: 基于Spring Boot的企业门户网站设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java springboot…...

Json解析流程
一、拿到了题库 分析一下可以定义的 1、序号,用来区分题目数,每个题有唯一的序号 2、题目,就是下图的Q 3、预设的回答,下图的A 分析完我可以知道有三个字段,分别是int index、string Q、string A。 二、把字段丢到…...

Mybatis 动态SQL – 使用choose标签动态生成条件语句
之前我们介绍了if,where标签的使用;本篇我们需要在if,where标签的基础上介绍如何使用Mybatis提供的choose标签动态生成条件语句。 如果您对if,where标签动态生成条件语句不太了解,建议您先进行了解后再阅读本篇,可以参考: Mybat…...
http接口自动化测试框架实现
目录 一、测试需求描述 二、实现方法 三、Excel表格样式 四、实现代码(代码才是王道,有注释很容易就能看明白的) 一、测试需求描述 对服务后台一系列的http接口功能测试。 输入:根据接口描述构造不同的参数输入值 输出&…...

Android逆向学习(三)vscode修改smali绕过vip
Android逆向学习(三)vscode修改smali绕过vip 写在前面 这是吾爱的第二个作业,主要就是要修改smali代码,其实smali代码我感觉没有必要去学,当然主要是我本来就会汇编语言,基本上汇编语言都是一样的&#x…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...