在cppreference中atomic_compare_exchange_weak的示例代码是否正确?

Kno*_*abe 8 c++ c++11

http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange上,以下示例代码作为示例使用std::atomic_compare_exchange_weak:

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while(! std::atomic_compare_exchange_weak(s->head, head, n));
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,这已经比较的效果*(s->head)head,当我所相信的希望是比较s->headhead.std::atomic_compare_exchange_weak在这个例子中&(s->head),第一个参数应该是,还是我错过了什么?

更新:规格std::atomic_compare_exchange_weak说:

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;
Run Code Online (Sandbox Code Playgroud)

效果:原子地,比较对象指向的内存的内容...与预期中的内容相等...

我认为这意味着*object与之相比较expected,但进一步的研究表明,实际意义是*object与之比较*expected(即,"在expected"中的意思是"指向expected").这意味着我原来问题的答案是"不,没有必要s->head在cppreference中获取示例代码中的地址".但object必须指向a std::atomic<T>和预期必须指向a 的事实T使我很难弄清楚如何在cppreference处更正代码以便编译.我们想要将列表的头部与列表头部的副本进行比较,但如果列表的头部是类型std::atomic<T>*,则T*如果调用的话,副本必须是类型的std::atomic_compare_exchange_weak是编译,我找不到一种方法来指定std::atomic<T>*一个T*没有a reinterpret_cast.即使这样,第三个参数std::atomic_compare_exchange_weak也需要是类型T,但cppreference中的示例显示第二个和第三个参数属于同一类型.这告诉我,cppreference的例子被打破了.我试图修复它,但是我被使用了一个reinterpret_cast只是感觉不对的需要而感到困扰.

有趣的是,在我试图弄清楚这些东西时,我检查了msdn页面std::atomic_compare_exchange_weak,我很惊讶地看到该页面显示了原型std::atomic_compare_exchange_*strong*!

有人可以发布用于std::atomic_compare_exchange_weak在单链表的前面插入节点的合理代码吗?没有必要担心ABA问题或做任何花哨的事情.我只想看到编译的骨架代码.

小智 2

一个正确的例子是:

struct list {
    std::atomic<node*> head;
};

...

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while (!std::atomic_compare_exchange_weak(&(s->head), &head, n));
    // or while (!s->head.compare_exchange_weak(head, n));
}
Run Code Online (Sandbox Code Playgroud)

除非您想处理未定义的行为,否则需要list::head是一个对象。std::atomic相关平台可能需要std::atomic使用锁来实现部分或全部功能。因此,std::atomic<T*>可能会包含其他成员,并且reinterpret_cast<std::atomic<T*>*>UB 意味着您的程序崩溃。