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

C++中关键字volatile和mutable用法相关推荐

  1. java中关键字volatile的作用(转载)

    转载:http://blog.csdn.net/orzorz/article/details/4319055 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对 ...

  2. 转:C++中const、volatile、mutable的用法

    const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的.它的含义是:const修饰的类型 ...

  3. C++中const、volatile、mutable的用法

    From: http://blog.csdn.net/wuliming_sc/article/details/3717017 const修饰普通变量和指针 const修饰变量,一般有两种写法: con ...

  4. [转] C++中 const, volatile, mutable用法

    const.volatile.mutable的用法 const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写 ...

  5. [转]C++中const、volatile、mutable的用法

    原文:https://blog.csdn.net/imJaron/article/details/79657642 const意思是"这个函数不修改对象内部状态". 为了保证这一点 ...

  6. C语言中的关键字“ volatile”的用法(摘)

    C语言中的关键字" volatile"的用法(摘) volatile 这个ANSI C 关键字在经典的C 教程中很少提及,高层编程的人也可能永远都 不会用到,但是作为嵌入式开发者来 ...

  7. C++基本功:全面掌握const、volatile和mutable关键字

    C++ 程式设计过程中 ,const 的使用可以频度是非常高的 . 它在保证程式安全方面起到了不可估量的作用 . 用一句话来表达最确切不过了:"小兵立大功" .    有了 con ...

  8. 如何理解 JAVA 中的 volatile 关键字

    如何理解 JAVA 中的 volatile 关键字 最近在重新梳理多线程,同步相关的知识点.关于 volatile 关键字阅读了好多博客文章,发现质量高适合小白的不多,最终找到一篇英文的非常通俗易懂. ...

  9. java中的Volatile关键字使用

    文章目录 什么时候使用volatile Happens-Before java中的Volatile关键字使用 在本文中,我们会介绍java中的一个关键字volatile. volatile的中文意思是 ...

最新文章

  1. ERR_PTR PTR_ERR IS_ERR ERROR
  2. pacman安装ubuntu_Ubuntu如何安装pacman
  3. [WPF]WPF中材质制作——图片和矢量图之争
  4. 数据机房建设常用材料有哪些?
  5. 简要说说一个完整机器学习项目的流程
  6. JZOJ 1322. 硬币游戏
  7. 程序员如何面对 HR 面试的 40 个问题
  8. 一套通用的后台管理系统Base Admin 前端:layui 后端:java
  9. 11. 王道考研-二叉树的实现
  10. 算法、数据结构和设计模式
  11. 高质量计算机学习网站
  12. linux raid卡驱动添加到内核,CentOS安装RAID卡驱动总结
  13. 企业微信获取企业凭证全流程
  14. 数据分析之数据处理(一)
  15. PS照片美化处理实例教程
  16. 北京CBD核心区有哪些值得加入的科技公司
  17. 清理zabbix监控中磁盘空间不足
  18. 机甲旋风为什么pk显示服务器响应,机甲旋风闪影转职技能与技巧解析
  19. 安卓笔记:修正Task ‘wrapper‘ not found in project
  20. php递归函数实用吗,php递归函数怎么用才有效

热门文章

  1. 物联网设备天线设计与选型指南
  2. 深度学习(2)基础2 -- 分类:得分函数损失函数(损失、正则化惩罚项、梯度下降、学习率)概率
  3. mac修改默认python版本_Anaconda/MacOS:更改默认python版本
  4. canny边缘检测 关于2个阈值参数
  5. Udacity机器人软件工程师课程笔记(二十二) - 物体识别 - 色彩直方图,支持向量机SVM
  6. 只需三分钟您就可以用nodejs搭建静态网页服务器(配置静态网页访问目录)
  7. [Nuxt.js]Nuxt项目启动如何跳过“Are you interested in participation?”
  8. Vyond制作2D动画学习教程
  9. blktrace 工具集使用 及其实现原理
  10. 装饰模式(Decorator)