当前位置: 首页 > news >正文

关于c++中mutable、const、volatile这三个关键字及对应c++与汇编示例源码

这哥三之间的关系是有趣的,不妨看看这个:

cv (const and volatile) type qualifiers - cppreference.com

mutable

permits modification of the class member declared mutable even if the containing object is declared const.

即便一个对象是const的,它内部的成员变量如果被mutable修饰,则此成员变量依旧可以被修改。

const

很常见,用途如其字面意义:别改变它"作用域"内的对象。

volatile

就如其含义:生性活泼,莫对其"作用域"下的对象指手画脚。这里着重说一下volatile。

volatile相关特性

        1. 易变性。所谓的易变性,在汇编层面反映出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是重新从内存中读取。
特性。

        2. "不可优化"特性。volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。
        3. "顺序性",能够保证volatile变量间的顺序性,编译器不会进行乱序优化。 C/C++ Volatile变量,与非Volatile变量之间的操作,是可能被编译器交换顺序的。C/C++ Volatile变量间的操作,是不会被编译器交换顺序的。哪怕将所有的变量全部都声明为volatile,哪怕杜绝了编译器的乱序优化,但是针对生成的汇编代码,CPU有可能仍旧会乱序执行指令,导致程序依赖的逻辑出错,volatile对此无能为力 针对这个多线程的应用,真正正确的做法,是构建一个happens-before语义(请见下面的内存顺序说明)。

特别注意的误区

volatile和多线程这种并行数据同步机制无关,也不能解决这类问题。相关问题请见:

内存顺序 std::memory_order - cppreference.com

const 和 volatile 关键字可更改处理指针的方式。 const 关键字指定指针在初始化后无法修改;此后指针将受到保护,防止进行修改。
volatile 关键字指定与后跟的名称关联的值可由用户应用程序中的操作以外的操作修改。 因此,volatile 关键字对于声明共享内存中可由多个进程访问的对象或用于与中断服务例程通信的全局数据区域很有用。
如果某个名称被声明为 volatile,则每当程序访问该名称时,编译器都会重新加载内存中的值。 这将显著减少可能的优化。 但是,当对象的状态可能意外更改时,这是保证可预见的程序性能的唯一方法。

如果将 struct 成员标记为 volatile,则 volatile 将传播到整个结构。 如果结构不具有可通过使用一个指令在当前体系结构上复制的长度,则此结构上可能完全丢失 volatile。

volatile 关键字失效

如果满足下列条件之一,则 volatile 关键字可能对字段不起作用:
        1. 可变字段的长度超过可使用一条指令在当前体系结构上复制的最大大小。
        2. 最外层包含 struct 的长度 - 或如果它是可能嵌套的 struct 的成员 - 超过可使用一条指令在当前体系结构上复制的最大大小。
尽管处理器不会对不可缓存的内存访问重新排序,但必须将不可缓存的变量标记为 volatile,从而保证此编译器不会对内存访问重新排序。
声明为 volatile 的对象不在某些优化中使用,因为它们的值可以随时更改。 系统在请求易失对象时始终读取该对象的当前值,即使前面的指令要求从同一对象获取值也是如此。 此外,对象的值会立即在赋值时写入。

volatile 原理源码示例

注:以下所有示例的c++源码一致,只区分是否使用volatile关键字

c++源程序:

#include <stdio.h>
int main(int argc, char** argv)
{auto sk = argc;int a = 11 << sk;int b = 19 + argc;int rv = a + b * 8;rv *= sk;return rv;
}

VS Debug环境MASM反汇编

没有使用volatile关键字修饰

反汇编代码:

00007FF7DE032993  mov         eax,dword ptr [argc]  
00007FF7DE032999  mov         dword ptr [sk],eax
00007FF7DE03299C  mov         eax,dword ptr [sk]  
00007FF7DE03299F  mov         ecx,0Bh  
00007FF7DE0329A4  mov         dword ptr [rbp+134h],ecx  
00007FF7DE0329AA  movzx       ecx,al  
00007FF7DE0329AD  mov         eax,dword ptr [rbp+134h]  
00007FF7DE0329B3  shl         eax,cl  
00007FF7DE0329B5  mov         dword ptr [a],eax
00007FF7DE0329B8  mov         eax,dword ptr [argc]  
00007FF7DE0329BE  add         eax,13h  
00007FF7DE0329C1  mov         dword ptr [b],eax
00007FF7DE0329C4  mov         eax,dword ptr [a]  
00007FF7DE0329C7  mov         ecx,dword ptr [b]  
00007FF7DE0329CA  lea         eax,[rax+rcx*8]  
00007FF7DE0329CD  mov         dword ptr [rv],eax
00007FF7DE0329D0  mov         eax,dword ptr [rv]  
00007FF7DE0329D3  imul        eax,dword ptr [sk]  
00007FF7DE0329D7  mov         dword ptr [rv],eax
00007FF7DE0329DA  mov         eax,dword ptr [rv]  
00007FF7DE0329DD  lea         rsp,[rbp+148h]  
00007FF7DE0329E4  pop         rdi  
00007FF7DE0329E5  pop         rbp  
00007FF7DE0329E6  ret

使用volatile关键字修饰

c++代码:

#include <stdio.h>
int main(int argc, char** argv)
{auto sk = argc;int a = 11 << sk;int b = 19 + argc;volatile int rv = a + b * 8;rv *= sk;return rv;
}

反汇编代码:

00007FF7F4102993  mov         eax,dword ptr [argc]  
00007FF7F4102999  mov         dword ptr [sk],eax
00007FF7F410299C  mov         eax,dword ptr [sk]  
00007FF7F410299F  mov         ecx,0Bh  
00007FF7F41029A4  mov         dword ptr [rbp+134h],ecx  
00007FF7F41029AA  movzx       ecx,al  
00007FF7F41029AD  mov         eax,dword ptr [rbp+134h]  
00007FF7F41029B3  shl         eax,cl  
00007FF7F41029B5  mov         dword ptr [a],eax
00007FF7F41029B8  mov         eax,dword ptr [argc]  
00007FF7F41029BE  add         eax,13h  
00007FF7F41029C1  mov         dword ptr [b],eax
00007FF7F41029C4  mov         eax,dword ptr [a]  
00007FF7F41029C7  mov         ecx,dword ptr [b]  
00007FF7F41029CA  lea         eax,[rax+rcx*8]  
00007FF7F41029CD  mov         dword ptr [rv],eax
00007FF7F41029D0  mov         eax,dword ptr [rv]  
00007FF7F41029D3  imul        eax,dword ptr [sk]  
00007FF7F41029D7  mov         dword ptr [rv],eax
00007FF7F41029DA  mov         eax,dword ptr [rv]
00007FF7F41029DD  lea         rsp,[rbp+148h]  
00007FF7F41029E4  pop         rdi  
00007FF7F41029E5  pop         rbp  
00007FF7F41029E6  ret

VS Release环境MASM反汇编

没有使用volatile关键字修饰

反汇编代码:

00007FF748801000  mov         eax,0Bh  
00007FF748801005  shl         eax,cl
00007FF748801007  lea         eax,[rax+rcx*8]  
00007FF74880100A  add         eax,98h
00007FF74880100F  imul        eax,ecx
00007FF748801012  ret

使用volatile关键字修饰

反汇编代码:

00007FF650C11005  shl         eax,cl
00007FF650C11007  lea         eax,[rax+rcx*8]  
00007FF650C1100A  add         eax,98h  
00007FF650C1100F  mov         dword ptr [rsp+8],eax
00007FF650C11013  mov         eax,dword ptr [rv]  
00007FF650C11017  imul        eax,ecx  
00007FF650C1101A  mov         dword ptr [rv],eax
00007FF650C1101E  mov         eax,dword ptr [rv]
00007FF650C11022  ret 

Linux GUN x86 64bit AT&T 环境优化参数O1反汇编

没有使用volatile关键字修饰

c++源码:

#include <stdio.h>
int main(int argc, char** argv)
{auto sk = argc;int a = 11 << sk;int b = 19 + argc;int rv = a + b * 8;rv *= sk;return rv;
}

反汇编代码:

0000 89F9     		movl	%edi, %ecx
0002 B80B0000 		movl	$11, %eax
0007 D3E0     		sall	%cl, %eax
0009 8D84F898 		leal	152(%rax,%rdi,8), %eax
0010 0FAFC7   		imull	%edi, %eax
0013 C3       		ret

使用volatile关键字修饰

c++源码:

#include <stdio.h>
int main(int argc, char** argv)
{auto sk = argc;int a = 11 << sk;int b = 19 + argc;volatile int rv = a + b * 8;rv *= sk;return rv;
}

反汇编代码:

0000 89F9     		movl	%edi, %ecx
0002 B80B0000 		movl	$11, %eax
0007 D3E0     		sall	%cl, %eax
0009 8D84F898 		leal	152(%rax,%rdi,8), %eax
0010 894424FC 		movl	%eax, -4(%rsp)
0014 8B4424FC 		movl	-4(%rsp), %eax
0018 0FAFC7   		imull	%edi, %eax
001b 894424FC 		movl	%eax, -4(%rsp)
001f 8B4424FC 		movl	-4(%rsp), %eax
0023 C3       		ret

总结:

        由上面的这些代码可以看到,非Debug环境有优化,但是因为volatile关键字的作用,有没有volatile关键字,优化后的汇编指令是不一样的。

关于Linux下AT&T格式汇编的详情请见: Linux c++反汇编源码细节解释说明_含影的博客-CSDN博客

如果使用GDB在Linux调试,GDB下载地址为: Index of /gnu/gdb

相关文章:

关于c++中mutable、const、volatile这三个关键字及对应c++与汇编示例源码

这哥三之间的关系是有趣的&#xff0c;不妨看看这个&#xff1a; cv (const and volatile) type qualifiers - cppreference.com mutable permits modification of the class member declared mutable even if the containing object is declared const. 即便一个对象是con…...

把大模型装进手机,分几步?

点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机&#xff0c;AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代&#xff0c;华为盘古大模型将会来助力鸿蒙生态。”8月4日&#xff0c;华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍&#xff0c…...

c++游戏制作指南(三):c++剧情类文字游戏的制作

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到静渊隐者的csdn博文&#xff0c;本文是c游戏制作指南的一部&#x1f35f; &#x1f355;更多文章请点击下方链接&#x1f355; &#x1f368; c游戏制作指南&#x1f3…...

Flutter系列文章-实战项目

在本篇文章中&#xff0c;我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识&#xff0c;包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用&#xff0c;可以根据用户输入的城市名获取该城市的天气信息&#xff0c;并将用户查询的城市列表保存到本地…...

HCIA---TCP/UDP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一.UDP协议简介 UDP协议的特点&#xff1a; 二.TCP协议简介 TCP协议特点 三.TCP和UDP的区别 思维导图 一.UDP协议简介 UDP&#xff08;User …...

数据库索引的使用

1、MySQL的基本架构 架构图 左边的client可以看成是客户端&#xff0c;客户端有很多&#xff0c;像我们经常你使用的CMD黑窗口&#xff0c;像我们经常用于学习的WorkBench&#xff0c;像企业经常使用的Navicat工具&#xff0c;它们都是一个客户端。右边的这一大堆都可以看成是…...

校验 GPT-4 真实性的三个经典问题:快速区分 GPT-3.5 与 GPT-4,并提供免费测试网站

现在已经有很多 ChatGPT 的套壳网站&#xff0c;以下分享验明 GPT-4 真身的三个经典问题&#xff0c;帮助你快速区分套壳网站背后到底用的是 GPT-3.5 还是 GPT-4。 大家可以在这个网站测试&#xff1a;https://ai.hxkj.vip&#xff0c;免登录可以问三条&#xff0c;登录之后无限…...

SpringBoot整合MongoDB连接池(含源码)

&#x1f4a1;版本依赖 jdk 17 SpringBoot 3.1.0 Mongo 6.0.8 mybatis-plus 2.0.2 &#x1f4a1;环境准备 &#x1f335;MongoDB安装 安装教程请查看&#xff1a;一文搞定(linuxwindowsdocker)安装MongoDB &#x1f335;导入依赖 <parent><groupId>org.sp…...

[oeasy]python0082_[趣味拓展]控制序列_清屏_控制输出位置_2J

光标位置 回忆上次内容 上次了解了键盘演化的过程 ESC 从 组合键到 独立按键 ESC的作用 是 进入 控制序列配置 控制信息控制信息 \033[y;xH 设置光标位置\033[2J 清屏 这到底怎么控制&#xff1f;&#xff1f;&#xff1f;&#x1f914;谁来实现这些功能&#xff1f; 控制…...

Zookeeper+kafka

目录 1. Zookeeper定义 2. Zookeeper工作机制 3. Zookeeper特点 4. Zookeeper数据结构 5. Zookeeper应用场景 5.1 统一命名服务 5.2 统一配置管理 5.3 统一集群管理 5.4 服务器动态上下线 5.5 软负载均衡 6. Zookeeper 选举机制 6.1 第一次启动选举机制 6.2 非第一…...

Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基础页面框架的静态设计(二)

Gpt微信小程序搭建的前后端流程 - 前端小程序部分-1.基础页面框架的静态设计(二) 在开始这个专栏&#xff0c;我们需要找一个小程序为参考&#xff0c;参考和仿照其界面&#xff0c;聊天交互模式。 这里参考小程序-小柠AI智能聊天&#xff0c;可自行先体验。 该小程序主要提供了…...

Flask进阶:构建RESTful API和数据库交互

在初级教程中&#xff0c;我们已经介绍了如何使用Flask构建基础的Web应用。在本篇中级教程中&#xff0c;我们将学习如何用Flask构建RESTful API&#xff0c;以及如何使用Flask-SQLAlchemy进行数据库操作。 一、构建RESTful API REST&#xff08;Representational State Tran…...

6.9(Java)二叉搜索树

1.我的代码: public class BinarySearchTree {class TreeNode {public int key;public TreeNode left;public TreeNode right;public TreeNode(int key) {this.key key;}}public TreeNode root; // 根节点// 插入一个元素,注意&#xff0c;不能插入重复的值&#xff0c;如…...

洛谷P2256 一中校运会之百米跑

题目背景 在一大堆秀恩爱的 ** 之中&#xff0c;来不及秀恩爱的苏大学神踏着坚定&#xff08;&#xff1f;&#xff09;的步伐走向了 100 100 100 米跑的起点。这时苏大学神发现&#xff0c;百米赛跑的参赛同学实在是太多了&#xff0c;连体育老师也忙不过来。这时体育老师发…...

python-opencv对极几何 StereoRectify

OpenCV如何正确使用stereoRectify函数 函数介绍 用于双目相机的立体校正环节中&#xff0c;这里只谈谈这个函数怎么使用&#xff0c;参数具体指哪些函数参数 随便去网上一搜或者看官方手册就能得到参数信息&#xff0c;但是&#xff01;&#xff01;相对关系非常容易出错&…...

pom文件---maven

027-Maven 命令行-实验四-生成 Web 工程-执行生成_ev_哔哩哔哩_bilibili 27节.后续补充 一.maven下载安装及配置 1)maven下载 2) settings文件配置本地仓库 3)settings配置远程仓库地址 4)配置maven工程的基础JDK版本 5)确认JDK环境变量配置没问题,配置maven的环境变量 验证…...

界面控件DevExpress.Drawing图形库早期增强功能分享

众所周知&#xff0c;DevExpress在v22.2发布周期中引入了全新的DevExpress.Drawing图形库&#xff08;并且已经在随后的小更新中引入了一系列增强功能&#xff09;。 在这篇博文中&#xff0c;我们将总结在DevExpress v23.1中解决的一些问题&#xff0c;以及在EAP构建中为以下…...

Semantic Kernel 入门系列:Connector连接器

当我们使用Native Function的时候&#xff0c;除了处理一些基本的逻辑操作之外&#xff0c;更多的还是需要进行外部数据源和服务的对接&#xff0c;要么是获取相关的数据&#xff0c;要么是保存输出结果。这一过程在Semantic Kernel中可以被归类为Connector。 Connector更像是…...

Maven介绍-下载-安装-使用-基础知识

Maven介绍-下载-安装-使用-基础知识 Maven的进阶高级用法可查看这篇文章&#xff1a; Maven分模块-继承-聚合-私服的高级用法 文章目录 Maven介绍-下载-安装-使用-基础知识01. Maven1.1 初识Maven1.1.1 什么是Maven1.1.2 Maven的作用 02. Maven概述2.1 Maven介绍2.2 Maven模型…...

Ansible环境搭建,CentOS 系列操作系统搭建Ansible集群环境

Ansible是一种自动化工具&#xff0c;基于Python写的&#xff0c;原理什么的就不过多再说了&#xff0c;详情参考&#xff1a;https://www.itwk.cc/post/403.html https://blog.csdn.net/qq_34185638/article/details/131079320?spm1001.2014.3001.5502 环境准备 HOSTNAMEIP…...

Simulink双矢量MPC实战:从郭磊磊论文到可运行的Matlab Function代码(调制模型预测控制详解)

Simulink双矢量MPC实战&#xff1a;从理论到代码的完整实现路径 当我在实验室第一次尝试复现郭磊磊老师那篇经典论文时&#xff0c;面对12种矢量组合和复杂的PWM生成逻辑&#xff0c;完全不知从何下手。经过三个月的反复试验和代码调试&#xff0c;终于摸清了从论文公式到可运行…...

基于vue的非遗文化传承平台[vue]-计算机毕业设计源码+LW文档

摘要&#xff1a;非物质文化遗产&#xff08;非遗&#xff09;作为民族文化的重要组成部分&#xff0c;承载着人类社会的文明和历史记忆。随着现代社会的快速发展&#xff0c;非遗文化的传承面临着诸多挑战。为了更好地保护和传承非遗文化&#xff0c;本文设计并实现了一个基于…...

LeetCode 热题100——3.无重复字符的最长子串

题目&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。注意 "bca" 和 "cab&qu…...

Matterport3D数据集:从全景构建到三维理解的实践指南

1. Matterport3D数据集全景解析 第一次接触Matterport3D数据集时&#xff0c;我被它庞大的数据规模震撼到了。这个数据集包含了90个完整的建筑场景&#xff0c;由194,400张RGB-D图像组成&#xff0c;覆盖了10,800个全景视角。简单来说&#xff0c;它就像是用专业相机把整栋房子…...

2026年4月如何集成OpenClaw?华为云保姆级10分钟安装及百炼APIKey配置方法

2026年4月如何集成OpenClaw&#xff1f;华为云保姆级10分钟安装及百炼APIKey配置方法。OpenClaw&#xff08;原Clawdbot&#xff09;作为2026年主流的AI自动化助理平台&#xff0c;可通过阿里云轻量服务器实现724小时稳定运行&#xff0c;并快速接入钉钉&#xff0c;让AI在企业…...

AI开发AI:借助快马多模型能力,迭代式构建你的智能健康管理Agent

最近在尝试开发一个健康管理AI助手&#xff0c;发现用传统方式写代码调试特别耗时。后来尝试了InsCode(快马)平台&#xff0c;发现用AI对话的方式迭代开发简直打开了新世界。记录下这个"用AI开发AI"的完整过程&#xff1a; 基础框架搭建 最开始只需要一个能交互的对话…...

CryptoJS不同加密模式对比:AES-CBC vs GCM在前端安全中的选择指南

AES加密模式深度解析&#xff1a;CBC与GCM在前端安全中的实战抉择 前端开发者在处理用户敏感数据时&#xff0c;AES加密已成为标配技术方案。但在具体实施过程中&#xff0c;加密模式的选择往往成为决策难点——是选择经典的CBC模式&#xff0c;还是拥抱更现代的GCM模式&#x…...

基于S7-300与组态王的智能药片装瓶机控制系统优化设计

1. 智能药片装瓶机控制系统的核心价值 在制药生产线上&#xff0c;药片装瓶环节看似简单却暗藏玄机。传统的人工装瓶方式不仅效率低下&#xff0c;还容易出现计数错误、交叉污染等问题。我曾在某药企亲眼见过工人因疲劳导致装瓶数量出错&#xff0c;最终整批药品不得不报废的案…...

Pixelorama:从像素小白到艺术大师的完整指南

Pixelorama&#xff1a;从像素小白到艺术大师的完整指南 【免费下载链接】Pixelorama Unleash your creativity with Pixelorama, a powerful and accessible open-source pixel art multitool. Whether you want to create sprites, tiles, animations, or just express yours…...

Hunyuan-MT-7B部署教程:Pixel Language Portal与Prometheus监控系统集成

Hunyuan-MT-7B部署教程&#xff1a;Pixel Language Portal与Prometheus监控系统集成 1. 项目概述 Pixel Language Portal是一款基于腾讯Hunyuan-MT-7B大模型构建的创新翻译工具&#xff0c;将传统翻译体验重构为16-bit像素冒险风格。本教程将指导您完成从基础部署到与Prometh…...