C ++ 0x |为什么std :: atomic使用volatile-qualifier重载每个方法?

时间:2011-02-02 04:48:09

标签: c++ c++11 volatile member-functions qualifiers

目前草案的以下摘录显示了我的意思:

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成员函数之间是否存在任何实现差异?换句话说,是否需要非易失性过载?

2 个答案:

答案 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);