IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 详解C/C++中volatile关键字 -> 正文阅读

[C++知识库]详解C/C++中volatile关键字

@著作权归作者所有:来自CSDN博客作者大胡子的艾娃的原创作品,如需转载,请注明出处https://blog.csdn.net/qq_43148810,否则将追究法律责任。
如有错误的地方欢迎指正,谢谢!

一、volatile介绍

volatile限定符和const很相似,起到对类型额外的修饰作用,并且和可以构成重载。

二、对类型额外的修饰作用

1、当对象的值可能在程序的控制和检测之外被改变时,应该对该对象声明为volatile。
2、声明volatile后对象的创建不发生reorder(1、先分配内存,再调用构造去初始化这块内存,最后将m_instance指针指向这块内存;2、先分配内存,再将m_instance指针指向这这段内存,最后调用构造去初始化这块内存。reorder就是是指1和2两种不定的情况。)
3、不会在两个操作之间把volatile变量缓存在寄存器中,都会直接从变量地址中读取数据,不会出现副本(寄存器)和实际内存值不一致的现象。
4、一般volatile对debug版无作用,debug一般不做优化。
5、非volatile的引用不能绑定到volatile对象
6、如果一个类希望拷贝、移动和赋值其volatile声明的对象功能,则必须自定义该版本的拷贝、移动和赋值函数。

三、volatile使用场景:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

四、构成重载

#include <iostream>
class My
{
public:
	void show()
	{
		std::cout << "test_and_set\n";
	}
	void show() volatile
	{
		std::cout << "volatile\n";
	}
};

int main()
{
	My my1;
	volatile My my2;
	my1.show();				//优先重载非volatile
	my2.show();
	return 0;
}

1、test_and_set和clear接口都重载了volatile 接口
2、同const一致,但互不影响。重载调用关系也和const一致,volatile对象只能调用volatile接口,非volatile优先重载非volatile接口。

五、标准库原子量std::atomic_flag的实现分析

		// STRUCT atomic_flag
#define ATOMIC_FLAG_INIT	{0}
typedef struct atomic_flag
	{	// structure for managing flag with test-and-set semantics
	bool test_and_set(memory_order _Order = memory_order_seq_cst) volatile noexcept;
	bool test_and_set(memory_order _Order = memory_order_seq_cst) noexcept;
	void clear(memory_order _Order = memory_order_seq_cst) volatile noexcept;
	void clear(memory_order _Order = memory_order_seq_cst) noexcept;

	_Atomic_flag_t _My_flag;

	atomic_flag() noexcept = default;
	atomic_flag(const atomic_flag&) = delete;
	atomic_flag& operator=(const atomic_flag&) = delete;
	atomic_flag& operator=(const atomic_flag&) volatile = delete;
	} atomic_flag;

inline bool atomic_flag::test_and_set(memory_order _Order) volatile noexcept
	{	// atomically set *this to true and return previous value
	return (_Atomic_flag_test_and_set(&_My_flag, _Order));
	}

inline bool atomic_flag::test_and_set(memory_order _Order) noexcept
	{	// atomically set *this to true and return previous value
	return (_Atomic_flag_test_and_set(&_My_flag, _Order));
	}

inline void atomic_flag::clear(memory_order _Order) volatile noexcept
	{	// atomically clear *this
	_Atomic_flag_clear(&_My_flag, _Order);
	}

inline void atomic_flag::clear(memory_order _Order) noexcept
	{	// atomically clear *this
	_Atomic_flag_clear(&_My_flag, _Order);
	}

inline bool atomic_flag_test_and_set(volatile atomic_flag *_Flag) noexcept
	{	// atomically set *_Flag to true and return previous value
	return (_Atomic_flag_test_and_set(&_Flag->_My_flag, memory_order_seq_cst));
	}

inline bool atomic_flag_test_and_set(atomic_flag *_Flag) noexcept
	{	// atomically set *_Flag to true and return previous value
	return (_Atomic_flag_test_and_set(&_Flag->_My_flag, memory_order_seq_cst));
	}

inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *_Flag, memory_order _Order) noexcept
	{	// atomically set *_Flag to true and return previous value
	return (_Atomic_flag_test_and_set(&_Flag->_My_flag, _Order));
	}

inline bool atomic_flag_test_and_set_explicit(atomic_flag *_Flag, memory_order _Order) noexcept
	{	// atomically set *_Flag to true and return previous value
	return (_Atomic_flag_test_and_set(&_Flag->_My_flag, _Order));
	}

inline void atomic_flag_clear(volatile atomic_flag *_Flag) noexcept
	{	// atomically clear *_Flag
	_Atomic_flag_clear(&_Flag->_My_flag, memory_order_seq_cst);
	}

inline void atomic_flag_clear(atomic_flag *_Flag) noexcept
	{	// atomically clear *_Flag
	_Atomic_flag_clear(&_Flag->_My_flag, memory_order_seq_cst);
	}

inline void atomic_flag_clear_explicit(volatile atomic_flag *_Flag, memory_order _Order) noexcept
	{	// atomically clear *_Flag
	_Atomic_flag_clear(&_Flag->_My_flag, _Order);
	}

inline void atomic_flag_clear_explicit(atomic_flag *_Flag, memory_order _Order) noexcept
	{	// atomically clear *_Flag
	_Atomic_flag_clear(&_Flag->_My_flag, _Order);
	}

1、test_and_set和clear均实现volatile和非volatile两个版本。
2、类atomic_flag用于多任务环境下各任务间共享的标志

更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-11 11:59:07  更:2021-08-11 11:59:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 0:05:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码