C++中关键字volatile和mutable用法
C/C++中的volatile关键字和const对应,用来修饰变量,用于告诉编译器该变量值是不稳定的,可能被更改。使用volatile注意事项:
(1). 编译器会对带有volatile关键字的变量禁用优化(A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided)。
(2). 当多个线程都要用到某一个变量且该变量的值会被改变时应该用volatile声明,该关键字的作用是防止编译器优化把变量从内存装入CPU寄存器中。如果变量被装入寄存器,那么多个线程有可能有的使用内存中的变量,有的使用寄存器中的变量,这会造成程序的错误执行。volatile的意思是让编译器每次操作该变量时一定要从内存中取出,而不是使用已经存在寄存器中的值(It cannot cache the variables in register)。
(3). 中断服务程序中访问到的变量最好带上volatile。
(4). 并行设备的硬件寄存器的变量最好带上volatile。
(5). 声明的变量可以同时带有const和volatile关键字。
(6). 多个volatile变量间的操作,是不会被编译器交换顺序的,能够保证volatile变量间的顺序性,编译器不会进行乱序优化(The value cannot change in order of assignment)。但volatile变量和非volatile变量之间的顺序,编译器不保证顺序,可能会进行乱序优化。
C++中的mutable关键字使用场景:
(1). 允许即使包含它的对象被声明为const时仍可修改声明为mutable的类成员(sometimes there is requirement to modify one or more data members of class/struct through const function even though you don’t want the function to update other members of class/struct. This task can be easily performed by using mutable keyword)。
(2). 应用在C++11 lambda表达式来表示按值捕获的值是可修改的,默认情况下是不可修改的,但修改仅在lambda式内有效(since c++11 mutable can be used on a lambda to denote that things captured by value are modifiable (they aren't by default))。
详细用法见下面的测试代码,下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "volatile_mutable.hpp"
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <mutex>
#include <string.h>namespace volatile_mutable_ {///
int test_volatile_1()
{volatile int i1 = 0; // correctint volatile i2 = 0; // correctreturn 0;
}///
// reference: https://en.cppreference.com/w/c/language/volatile
int test_volatile_2()
{
{ // Any attempt to read or write to an object whose type is volatile-qualified through a non-volatile lvalue results in undefined behaviorvolatile int n = 1; // object of volatile-qualified typeint* p = (int*)&n;int val = *p; // undefined behavior in C, Note: link does not report an error under C++fprintf(stdout, "val: %d\n", val);
}{ // A member of a volatile-qualified structure or union type acquires the qualification of the type it belongs totypedef struct ss { int i; const int ci; } s;// the type of s.i is int, the type of s.ci is const intvolatile s vs = { 1, 2 };// the types of vs.i and vs.ci are volatile int and const volatile int
}{ // If an array type is declared with the volatile type qualifier (through the use of typedef), the array type is not volatile-qualified, but its element type istypedef int A[2][3];volatile A a = { {4, 5, 6}, {7, 8, 9} }; // array of array of volatile int//int* pi = a[0]; // Error: a[0] has type volatile int*volatile int* pi = a[0];
}{ // A pointer to a non-volatile type can be implicitly converted to a pointer to the volatile-qualified version of the same or compatible type. The reverse conversion can be performed with a cast expressionint* p = nullptr;volatile int* vp = p; // OK: adds qualifiers (int to volatile int)//p = vp; // Error: discards qualifiers (volatile int to int)p = (int*)vp; // OK: cast
}{ // volatile disable optimizationsclock_t t = clock();double d = 0.0;for (int n = 0; n < 10000; ++n)for (int m = 0; m < 10000; ++m)d += d * n*m; // reads and writes to a non-volatile fprintf(stdout, "Modified a non-volatile variable 100m times. Time used: %.2f seconds\n", (double)(clock() - t) / CLOCKS_PER_SEC);t = clock();volatile double vd = 0.0;for (int n = 0; n < 10000; ++n)for (int m = 0; m < 10000; ++m)vd += vd * n*m; // reads and writes to a volatile fprintf(stdout, "Modified a volatile variable 100m times. Time used: %.2f seconds\n", (double)(clock() - t) / CLOCKS_PER_SEC);
}return 0;
}///
// reference: https://en.cppreference.com/w/cpp/language/cv
int test_volatile_3()
{int n1 = 0; // non-const objectconst int n2 = 0; // const objectint const n3 = 0; // const object (same as n2)volatile int n4 = 0; // volatile objectconst struct {int n1;mutable int n2;} x = { 0, 0 }; // const object with mutable membern1 = 1; // ok, modifiable object//n2 = 2; // error: non-modifiable objectn4 = 3; // ok, treated as a side-effect//x.n1 = 4; // error: member of a const object is constx.n2 = 4; // ok, mutable member of a const object isn't constconst int& r1 = n1; // reference to const bound to non-const object//r1 = 2; // error: attempt to modify through reference to constconst_cast<int&>(r1) = 2; // ok, modifies non-const object n1fprintf(stdout, "n1: %d\n", n1); // 2const int& r2 = n2; // reference to const bound to const object//r2 = 2; // error: attempt to modify through reference to constconst_cast<int&>(r2) = 2; // undefined behavior: attempt to modify const object n2, Note: link does not report an error under C++fprintf(stdout, "n2: %d\n", n2); // 0return 0;
}///
// reference: https://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/
int test_volatile_4()
{
{const int local = 10;int *ptr = (int*)&local;fprintf(stdout, "Initial value of local : %d \n", local); // 10*ptr = 100;fprintf(stdout, "Modified value of local: %d \n", local); // 10
}{const volatile int local = 10;int *ptr = (int*)&local;fprintf(stdout, "Initial value of local : %d \n", local); // 10*ptr = 100;fprintf(stdout, "Modified value of local: %d \n", local); // 100
}return 0;
}///
// reference: https://en.cppreference.com/w/cpp/language/cv
int test_mutable_1()
{// Mutable is used to specify that the member does not affect the externally visible state of the class (as often used for mutexes,// memo caches, lazy evaluation, and access instrumentation)class ThreadsafeCounter {public:int get() const {std::lock_guard<std::mutex> lk(m);return data;}void inc() {std::lock_guard<std::mutex> lk(m);++data;}private:mutable std::mutex m; // The "M&M rule": mutable and mutex go togetherint data = 0;};return 0;
}///
// reference: https://www.tutorialspoint.com/cplusplus-mutable-keyword
int test_mutable_2()
{class Test {public:Test(int x = 0, int y = 0) : a(x), b(y) {}void seta(int x = 0) { a = x; }void setb(int y = 0) { b = y; }void disp() { fprintf(stdout, "a: %d, b: %d\n", a, b); }public:int a;mutable int b;};const Test t(10, 20);fprintf(stdout, "t.a: %d, t.b: %d \n", t.a, t.b); // 10, 20//t.a=30; // Error occurs because a can not be changed, because object is constant.t.b = 100; // b still can be changed, because b is mutable.fprintf(stdout, "t.a: %d, t.b: %d \n", t.a, t.b); // 10, 100return 0;
}///
// reference: https://www.geeksforgeeks.org/c-mutable-keyword/
int test_mutable_3()
{using std::cout;using std::endl;class Customer {public:Customer(char* s, char* m, int a, int p){strcpy(name, s);strcpy(placedorder, m);tableno = a;bill = p;}void changePlacedOrder(char* p) const { strcpy(placedorder, p); }void changeBill(int s) const { bill = s; }void display() const{cout << "Customer name is: " << name << endl;cout << "Food ordered by customer is: " << placedorder << endl;cout << "table no is: " << tableno << endl;cout << "Total payable amount: " << bill << endl;}private:char name[25];mutable char placedorder[50];int tableno;mutable int bill;};const Customer c1("Pravasi Meet", "Ice Cream", 3, 100);c1.display();c1.changePlacedOrder("GulabJammuns");c1.changeBill(150);c1.display();return 0;
}///
// reference: https://stackoverflow.com/questions/105014/does-the-mutable-keyword-have-any-purpose-other-than-allowing-the-variable-to
int test_mutable_4()
{int x = 0;auto f1 = [=]() mutable { x = 42; }; // OK//auto f2 = [=]() { x = 42; }; // Error: a by-value capture cannot be modified in a non-mutable lambdafprintf(stdout, "x: %d\n", x); // 0return 0;
}} // namespace volatile_mutable_
GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:
基于生成对抗网络(GAN)的人脸变形(附链接) | CSDN博文精选
扫码参与CSDN“原力计划”翻译 | 张一豪校对 | 吴金笛来源 | 数据派THU*点击阅读原文,查看「CSDN原力计划」详细说明。本文详细介绍了生成对抗网络(GAN)的知识,并用其变换人脸,并探寻如何利用StyleGAN生成不同属性&…

Jmeter连接Oracle数据库
一、Jmeter要连接oracle数据库,就必须复制JDBC驱动jar包文件ojdbc14.jar到Jmeter的lib目录下二、进入Jmeter的bin目录运行Jmeter.bat,启动Jmeter三、Jmeter软件配置如下:1、添加线程组右击线程组,选择“添加--配置元件--JDBC Conn…

swift3.0友盟分享
经过(一)的讲解,大家应该可以按照友盟提供的测试账号可以集成友盟分享了,友盟目前集合了18个APP共27种分享,可以授权的有10个App:微信、QQ、新浪微博、腾讯微博、人人网、豆瓣、Facebook、Twitter、Linkedi…

C++11中std::future的使用
C11中的std::future是一个模板类。std::future提供了一种用于访问异步操作结果的机制。std::future所引用的共享状态不能与任何其它异步返回的对象共享(与std::shared_future相反)( std::future references shared state that is not shared with any other asynchronous retur…
给算法工程师和研究员的「霸王餐」| 附招聘信息
现在的算法工程师真的是太难了!要让AI会看人眼都分辨不清的医疗影像!数据又不够,还得用前沿技术!好不容易学会看片,还要让AI会分析病理!然后模型搞出来了,还要把几十种模型,做N次计算…

swift3.0三种反向传值
一 :通知 1.通知传值所用方法 // MARK: - private methods(内部接口) let NotifMycation NSNotification.Name(rawValue:"MyNSNotification") func tempbuttonAction() { //这个方法可以传一个值 NotificationCenter.default.post(name: NotifMycation, object: &q…

C++11中std::shared_future的使用
C11中的std::shared_future是个模板类。与std::future类似,std::shared_future提供了一种访问异步操作结果的机制;不同于std::future,std::shared_future允许多个线程等待同一个共享状态;不同于std::future仅支持移动操作…
聊聊抖音、奈飞、Twitch、大疆、快手、B站的多媒体关键技术
随着5G牌照发放,5G终端正在迎来集中上市潮,对于5G带来的变革一触即发。目前互联网上超过七成的流量来自多媒体,未来这个比例将超过八成。音视频就像空气和水一样普及,深度到每个人的生活和工作中。同时,深度学习技术则…

Linux安全事件应急响应排查方法总结
Linux安全事件应急响应排查方法总结 Linux是服务器操作系统中最常用的操作系统,因为其拥有高性能、高扩展性、高安全性,受到了越来越多的运维人员追捧。但是针对Linux服务器操作系统的安全事件也非常多的。攻击方式主要是弱口令攻击、远程溢出攻击及其他…

C++11中std::packaged_task的使用
C11中的std::packaged_task是个模板类。std::packaged_task包装任何可调用目标(函数、lambda表达式、bind表达式、函数对象)以便它可以被异步调用。它的返回值或抛出的异常被存储于能通过std::future对象访问的共享状态中。 std::packaged_task类似于std::function,…

Swift3.0和OC桥接方法
1.直接在工程中commandn,出现如图,点击Header File创建桥接文件Bridging-Header.h,如图: 2.点击next,出现如图画面,一定要记得勾选第一项,再点击create创建完成。 3.配置桥接文件,点击target - …

量子算命,在线掷筊:一个IBM量子云计算机的应用实践,代码都有了
整理 | Jane 出品| AI科技大本营(ID:rgznai100) “算命”,古今中外,亘古不衰的一门学问,哪怕到了今天,大家对算命占卜都抱着一些”敬畏“的信任心理,西方流行塔罗牌,国…

rails应用ajax之二:使用rails自身支持
考虑另一种情况: 1. 页面上半部分显示当前的所有用户,页面下半部分是输入新用户的界面; 2. 每当输入新用户时,页面上半部分会动态更新新加用户的内容; 我们还是用ajax实现,不过这次用rails内部对ajax的支持…

C++11中std::async的使用
C11中的std::async是个模板函数。std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对象。Fn返回的值可通过std::future对象的get成员函数获取。一旦完成Fn的执行&…
BAT数据披露:缺人!110万AI人才缺口,两者矛盾,凉凉了!
人工智能到底有多火?近日国内首份《BAT人工智能领域人才发展报告》新鲜出炉,此次报告是针对国内人工智能领域的人才争夺情况进行了梳理。并把研究对象锁定在BAT三大巨头的身上。来源:《BAT人工智能领域人才发展报告》其中得出最为核心的结论&…

swift3.0最新拨打电话方法
let alertVC : UIAlertController UIAlertController.init(title: "是否拨打报警电话:10086", message: "", preferredStyle: .alert) let falseAA : UIAlertAction UIAlertAction.init(title: "取消", style: .cancel, handler: nil) let tr…

关于手机已处理里重复单据的处理办法
更新视图 VWFE_TASK去掉 union TWFE_TASK_BAK 的部分,原因是因为后面做了流程预演导致的问题转载于:https://blog.51cto.com/iderun/1602828

swiftswift3.0自己封装的快速构建页面的方法
//#param mark 控件 func creatLabel(frame:CGRect,text:String,textColor:UIColor,textFont:CGFloat,textAlignment:NSTextAlignment) -> UILabel { let label UILabel.init(frame: frame) label.text text label.textColor textColor label.font UIFont.systemFont(of…
Google是如何做Code Review的?| CSDN原力计划
作者 | 帅昕 xindoo 编辑 | 屠敏出品 | CSDN 博客我和几个小伙伴一起翻译了Google前一段时间放出来的Google’s Engineering Practices documentation(https://github.com/google/eng-practices),翻译后的GitHub仓库:https://gith…

从FFmpeg 4. 2源码中提取dshow mjpeg code步骤
之前在https://blog.csdn.net/fengbingchun/article/details/103735560 中介绍过在Windows上通过vs2017编译FFmpeg源码进行单步调试的步骤,为了进一步熟悉FFmpeg这里以提取FFmpeg dshow mjpeg源码为例介绍其实现过程及注意事项: FFmpeg是用C实现的&…

ControlButton按钮事件
#ifndef __HControlButton_H__#define __HControlButton_H__#include "cocos2d.h"#include "cocos-ext.h"USING_NS_CC;USING_NS_CC_EXT; //用于标识当前按钮的状态typedef enum{ touch_begin, touch_down, touch_up,}tagForTouch;class HControlB…

swift3.0UIAlertController使用方法
let alertVC : UIAlertController UIAlertController.init(title: "添加照片", message: "", preferredStyle: .actionSheet) let cleanAction UIAlertAction(title: "取消", style: UIAlertActionStyle.cancel,handler:nil) let photoActi…

Doxygen使用介绍
Doxygen的主页为http://doxygen.nl/,它的license为GPL,最新发布版本为1.8.17,源代码存放在https://github.com/doxygen/doxygen,它支持的语言包括C、C、Objective-C、C#、Java、Python等,它支持的系统平台包括Winodws、…
云计算软件生态圈:摸到一把大牌
作者 | 老姜编辑 | 阿秃出品 | CSDN云计算(ID:CSDNcloud)“我觉得我摸着了一把大牌。”软件领域的新锐企业——有赞公司创始人兼CEO白鸦在转向SaaS领域的一个细分市场时,曾对天使投资人这样说。而老牌软件企业金蝶创始人徐少春在2…

iOS封装HTTPS双向和单向验证
1.HttpsUtil (1) 对双向和单向验证的封装 #import <Foundation/Foundation.h> #import "AFNetworking.h" interface HttpsUtil : NSObject // 双向认证 (void)configHTTPSessionManager:(AFHTTPSessionManager *)manager serverCers:(NSArray *) serverCerNam…

开源库BearSSL介绍及使用
BearSSL是用C语言实现的SSL/TLS协议,它的源码可直接通过git clone https://www.bearssl.org/git/BearSSL 下载,它的license是MIT,最新版本为0.6。 BearSSL的主要特性是: (1). 正确且安全:对不安全的协议版本和算法选…
个推CTO安森:我所理解的数据中台
作者 | 个推CTO安森来源 | 个推技术学院(ID:ID: getuitech)引言在前面两篇文章(《数据智能时代来临:本质及技术体系要求》和《多维度分析系统的选型方法》)之中,我们概括性地阐述了对于数据智能的理解&…

玩弹珠手游-杂想
前言 为什么会写这个杂想呢? 因为最近这一个月来,我有点太沉迷怪物弹珠这个游戏了,每天下班回来的时间和上下班路途都在玩这个游戏,占据了我大部分的业余时间,也该是时候放一放玩游戏了。 为什么会玩这个游戏呢&#x…

OC封装时间选择器
#import <UIKit/UIKit.h> protocol TimeDatePickerViewDelegate <NSObject> //必须实现的两个协议 required - (void)changeTime : (NSDate *)date;//当时改变时出发 - (void)daterMine : (NSDate *)date;//更确定时间 end interface TimeDatePickerView :UIView /…