The following code example is given at http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange as an example of using 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)); }
My understanding is that this has the effect of comparing *(s->head) with head , when it seems to me desirable to compare s->head with head . If the first argument std::atomic_compare_exchange_weak in this example should be &(s->head) , or am I missing something?
UPDATE: specification for std::atomic_compare_exchange_weak says:
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;
Effects: Atomic, compares the contents of the memory pointed to by the object ... for equality with the expected ...
I believed that *object compared to expected , but further research shows that the actual value is that *object compared to *expected (that is, in expected "means" which the expected points to "). That would mean that the answer to my original question is βno, there is no need to take the address s->head in the example code in cppreference.β But the fact that object must point to std::atomic<T> , and the expected one must point to a T , makes it difficult for me to figure out how to fix the code in cppreference so that it compiles, we want to compare the list heading with a copy of the head of the list, but whether the head of the list is of type std::atomic<T>* , the copy must be of type T* , if the call to std::atomic_compare_exchange_weak is to compile, and I cannot find a way to assign std::atomic<T>* T* without reinterpret_cast Even then, the third parameter std::atomic_compare_exchange_weak must be of type T , but the cppreference example shows both the second and third parameters of the same type, which indicates that the cppreference example is broken. I tried to fix it, but I was stymied by the need to use reinterpret_cast , which just feels wrong.
Interestingly, in my attempts to figure this out, I checked the msdn page for std::atomic_compare_exchange_weak , and I was alarmed to see prototypes for std::atomic_compare_exchange_*strong* !
Can someone post plausible code that uses std::atomic_compare_exchange_weak to insert a node at the beginning of a singly linked list? There is no need to worry about the ABA problem or do something unusual. I would just like to compile skeletal code.