默认初始化标准::原子<;T*>;vs无锁堆栈 在威廉姆斯的C++并发操作第二中。第213页有一个无锁栈的实现(如下所示)。它泄漏节点,因此是不完整的,但这与我的问题无关。我的问题是他没有显式初始化std::atomic head指针,然后在pop()函数中取消引用它——这不是未定义的行为吗

默认初始化标准::原子<;T*>;vs无锁堆栈 在威廉姆斯的C++并发操作第二中。第213页有一个无锁栈的实现(如下所示)。它泄漏节点,因此是不完整的,但这与我的问题无关。我的问题是他没有显式初始化std::atomic head指针,然后在pop()函数中取消引用它——这不是未定义的行为吗,c++,C++,据 默认初始化的std::atomic不包含T对象,其唯一有效用途是通过std::atomic_init 所有指针类型的部分专门化std::atomic。这些专门化具有标准布局、普通默认构造函数和普通析构函数 我想我看不到什么,因为(甚至更不完整) 在上实现无锁堆栈也不重要 初始化原子头指针。有人能给我解释一下为什么这个用法是合法的吗 这是Wiliams的密码 template<typename T> class lock_free_stack { private: str

默认初始化的
std::atomic
不包含T对象,其唯一有效用途是通过
std::atomic_init

所有指针类型的部分专门化
std::atomic
。这些专门化具有标准布局、普通默认构造函数和普通析构函数

我想我看不到什么,因为(甚至更不完整) 在上实现无锁堆栈也不重要 初始化原子头指针。有人能给我解释一下为什么这个用法是合法的吗

这是Wiliams的密码

template<typename T>
class lock_free_stack
{
private:
    struct node
    {
        std::shared_ptr<T> data;
        node* next;
        node(T const& data_):
            data(std::make_shared<T>(data_))
        {}
    };
    std::atomic<node*> head;  // <-- Default constructor
public:
    void push(T const& data)
    {
        node* const new_node=new node(data);
        new_node->next=head.load();
        while(!head.compare_exchange_weak(new_node->next,new_node));
    }
    std::shared_ptr<T> pop()
    {
        node* old_head=head.load();
        while(old_head &&
              !head.compare_exchange_weak(old_head,
                                          old_head->next));// uninitialized ptr?
        return old_head ? old_head->data : std::shared_ptr<T>();
    }
};
模板
类锁\u自由\u堆栈
{
私人:
结构节点
{
std::共享的ptr数据;
节点*下一步;
节点(T常数和数据):
数据(标准::使共享(数据))
{}
};
std::atomic head;//next=head.load();
而(!head.compare_exchange_弱(新建节点->下一步,新建节点));
}
std::共享的\u ptr pop()
{
节点*old_head=head.load();
当(老)头&&
!头。比较你的交换弱(老头,
旧头->下一步);//未初始化的ptr?
返回旧头?旧头->数据:std::shared_ptr();
}
};

只有在读取时未初始化的变量,才能读取未初始化的变量。如果在读取之前先用一个值初始化它,就可以了。@Nicolas如果我没弄错的话,这两个函数都读取(并实际使用)存储在默认初始化头指针中的值。更糟糕的是,pop()取消了对这个指针的引用。另外,
无锁栈的构造函数在哪里?@nicolabolas似乎只有合成的默认构造函数。据我所知,威廉姆斯说——除了泄漏节点之外——这应该是一个完整的实现。换句话说——这正是我的问题,我们是否必须在堆栈的构造函数中将head初始化为nullptr。