C++ 原子比较交换的示例代码在CPPPreference处是否弱?

C++ 原子比较交换的示例代码在CPPPreference处是否弱?,c++,c++11,C++,C++11,在,以下示例代码作为std::atomic\u compare\u exchange\u 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)); } 我的理解是,这具有

在,以下示例代码作为
std::atomic\u compare\u exchange\u 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));
}
我的理解是,这具有将
*(s->head)
head
进行比较的效果,而我认为需要将
s->head
head
进行比较。在本例中,
std::atomic\u compare\u exchange\u weak
的第一个参数是
&(s->head)
,还是我遗漏了什么

更新:std::atomic\u compare\u exchange\u 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;
效果:原子地比较内存的内容 由对象指向…与预期中的相等

我认为这意味着将
*对象
预期的
进行比较,但进一步的研究表明,实际意义是将
*对象
*预期的
进行比较(即,“in
预期的
”表示“由
预期的
指向”)。这意味着对我的原始问题的回答是“不,没有必要在引用的示例代码中使用
s->head
的地址”。但是
object
必须指向
std::atomic
,expected必须指向
T
这一事实让我很难找出如何在cppreference处更正代码以便编译。我们想将列表的头与列表头的副本进行比较,但如果列表头的类型为
std::atomic*
,则如果要编译对
std::atomic\u compare\u exchange\u弱
的调用,则副本必须为
T*
,我找不到一种方法,在没有重新解释转换的情况下,将
std::atomic*
分配给
t*
。即使如此,
std::atomic\u compare\u exchange\u weak
的第三个参数也需要是
T
类型,但CPPFREFERENCE中的示例显示第二个和第三个参数都是相同类型的。这对我来说意味着cppreference的例子是不正确的。我试图修复它,但由于需要使用感觉不对劲的
重新解释cast
,我被阻碍了

有趣的是,在我试图弄明白这一点的过程中,我查看了,我很沮丧地看到该页面显示了
std::atomic\u compare\u exchange\u*strong*
的原型


有人能发布一些合理的代码,使用
std::atomic\u compare\u exchange\u weak
在单链表的前面插入一个节点吗?没有必要担心ABA问题或做任何花哨的事情。我只想看看编译的框架代码。

一个正确的例子是:

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));
}
struct列表{
原子头;
};
...
无效附加(列表*s,节点*n)
{
节点*头;
做{
头部=s->头部;
n->next=头部;
}而(!std::atomic_compare_exchange_弱(&(s->head),&head,n));
//或者当(!s->head.compare_exchange_弱(head,n));
}

除非您想处理未定义的行为,否则
list::head
必须是
std::atomic
对象。讨论中的平台可能需要使用锁实现部分或全部
std::atomic
东西。因此,
std::atomic
可能包含额外的成员,
reinterpret\u cast
可能是UB意味着程序崩溃的情况。

是不是
node
应该是一个原子对象?这是cppreference中完整的代码片段,但我认为它不会影响我问题的答案。代码是胡说八道。
atomic\u compare\u exchange\u weak
的第一个参数应该是指向原子类型对象的指针;第二个参数应该是指向相应值类型的对象的指针;第三个参数是对应值类型的对象(不是指针)。对于MSDN问题,
atomic\u compare\u exchange\u弱
atomic\u compare\u exchange\u强
的签名相同;只是名字不同。这只是一个剪切粘贴错误,在原子学中很常见,因为它看起来很像。除此之外,文档是正确的。我现在删除了这个示例(毕竟它是一个wiki),因为它确实是错误的。一旦围绕它构建了适当的框架,它就会编译。A可从IDEOne获得。我没有测试示例代码以确保其工作,但至少它可以编译。