目前草案的以下摘录显示了我的意思:
namespace std {
typedef struct atomic_bool {
bool is_lock_free() const volatile;
bool is_lock_free() const;
void store(bool, memory_order = memory_order_seq_cst) volatile;
void store(bool, memory_order = memory_order_seq_cst);
bool load(memory_order = memory_order_seq_cst) const volatile;
bool load(memory_order = memory_order_seq_cst) const;
operator bool() const volatile;
operator bool() const;
bool exchange(bool, memory_order = memory_order_seq_cst) volatile;
bool exchange(bool, memory_order = memory_order_seq_cst);
bool compare_exchange_weak(bool&, bool, memory_order, memory_order) volatile;
bool compare_exchange_weak(bool&, bool, memory_order, memory_order);
bool compare_exchange_strong(bool&, bool, memory_order, memory_order) volatile;
bool compare_exchange_strong(bool&, bool, memory_order, memory_order);
bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst) volatile;
bool compare_exchange_weak(bool&, bool, memory_order = memory_order_seq_cst);
bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst) volatile;
bool compare_exchange_strong(bool&, bool, memory_order = memory_order_seq_cst);
atomic_bool() = default;
constexpr atomic_bool(bool);
atomic_bool(const atomic_bool&) = delete;
atomic_bool& operator=(const atomic_bool&) = delete;
atomic_bool& operator=(const atomic_bool&) volatile = delete;
bool operator=(bool) volatile;
} atomic_bool;
}
易失性是传递性的。因此,您无法从易失性对象中调用非易失性成员函数。另一方面,允许从非易失性对象调用volatile成员函数。
那么,原子类中的volatile和非volatile成员函数之间是否存在任何实现差异?换句话说,是否需要非易失性过载?
答案 0 :(得分:4)
我认为由于效率原因存在易失性重载。易失性读取和写入本质上比C ++ 0x中的非易失性读取和写入更昂贵,因为内存模型提出了一些严格的要求,以防止缓存volatile变量的值。如果所有函数都只标记为volatile,那么代码不一定会进行某些优化,否则会提高性能。具有这种区别允许编译器在可能的情况下优化非易失性读取和写入,同时在需要进行易失性读取和写入时优雅地降级。
答案 1 :(得分:-1)
首先,制作易变的std :: atomic听起来多余。实际上,我可以想象一个有用的情况。假设我们有一个固定的设备(内存)地址,我们想要操作。由于std :: atomic_xxx类以及std :: atomic<>模板类大小应该与它们对应的内置类型大小相同,您可能希望同时处理两者:通过控制内存排序来执行原子操作,并确保永远不会优化对原子对象的访问。因此,我们可以声明如下:
std::atomic<long> volatile* vmem_first4 = reinterpret_cast<std::atomic<long> volatile*>(0xxB8000);