# std::atomic_compare_exchange_weak, std::atomic_compare_exchange_strong, std::atomic_compare_exchange_weak_explicit, std::atomic_compare_exchange_strong_explicit

From cppreference.com
< cpp‎ | atomic

Defined in header `<atomic>` |  |
| (1) | (since C++11)
template< class T > bool atomic_compare_exchange_weak( std::atomic<T>* obj, T* expected, T desired ); |  |
template< class T > bool atomic_compare_exchange_weak( volatile std::atomic<T>* obj, T* expected, T desired ); |  |
| (2) | (since C++11)
template< class T > bool atomic_compare_exchange_strong( std::atomic<T>* obj, T* expected, T desired ); |  |
template< class T > bool atomic_compare_exchange_strong( volatile std::atomic<T>* obj, T* expected, T desired ); |  |
| (3) | (since C++11)
template< class T > bool atomic_compare_exchange_weak_explicit( std::atomic<T>* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail ); |  |
template< class T > bool atomic_compare_exchange_weak_explicit( volatile std::atomic<T>* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail ); |  |
| (4) | (since C++11)
template< class T > bool atomic_compare_exchange_strong_explicit( std::atomic<T>* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail ); |  |
template< class T > bool atomic_compare_exchange_strong_explicit( volatile std::atomic<T>* obj, T* expected, T desired, std::memory_order succ, std::memory_order fail ); |  |

Atomically compares the object representation of the object pointed to by `obj` with the object representation of the object pointed to by `expected`, as if by std::memcmp, and if those are bitwise-equal, replaces the former with `desired` (performs read-modify-write operation). Otherwise, loads the actual value pointed to by `obj` into `*expected` (performs load operation). Copying is performed as if by std::memcpy.

The memory models for the read-modify-write and load operations are `succ` and `fail` respectively. The (1-2) versions use std::memory_order_seq_cst by default.

These functions are defined in terms of member functions of std::atomic:

1) obj->compare_exchange_weak(*expected, desired)
2) obj->compare_exchange_strong(*expected, desired)
3) obj->compare_exchange_weak(*expected, desired, succ, fail)
4) obj->compare_exchange_strong(*expected, desired, succ, fail)

### Parameters

obj | - | pointer to the atomic object to test and modify
expected | - | pointer to the value expected to be found in the atomic object
desired | - | the value to store in the atomic object if it is as expected
succ | - | the memory synchronization ordering for the read-modify-write operation if the comparison succeeds. All values are permitted.
fail | - | the memory synchronization ordering for the load operation if the comparison fails. Cannot be std::memory_order_release or std::memory_order_acq_rel and cannot specify stronger ordering than `succ` (until C++17)

### Return value

The result of the comparison: true if `*obj` was equal to `*expected`, false otherwise.

### Exceptions

`noexcept` specification:
noexcept

### Notes

The weak forms ((1) and (3)) of the functions are allowed to fail spuriously, that is, act as if *obj != *expected even if they are equal. When a compare-and-exchange is in a loop, the weak version will yield better performance on some platforms.

When a weak compare-and-exchange would require a loop and a strong one would not, the strong one is preferable unless the object representation of `T` may include padding bits, trap bits, or offers multiple object representations for the same value (e.g. floating-point NaN). In those cases, weak compare-and-exchange typically works because it quickly converges on some stable object representation.

### Example

compare and exchange operations are often used as basic building blocks of lockfree data structures

Run this code

    #include <atomic>

    template<class T>
    struct node
    {
        T data;
        node* next;
        node(const T& data) : data(data), next(nullptr) {}
    };

    template<class T>
    class stack
    {
        std::atomic<node<T>*> head;
     public:
        void push(const T& data)
        {
            node<T>* new_node = new node<T>(data);

            // put the current value of head into new_node->next
            new_node->next = head.load(std::memory_order_relaxed);

            // now make new_node the new head, but if the head
            // is no longer what's stored in new_node->next
            // (some other thread must have inserted a node just now)
            // then put that new head into new_node->next and try again
            while(!std::atomic_compare_exchange_weak_explicit(
                                    &head,
                                    &new_node->next,
                                    new_node,
                                    std::memory_order_release,
                                    std::memory_order_relaxed))
                    ; // the body of the loop is empty
    // note: the above loop is not thread-safe in at least
    // GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
    // MSVC prior to 2014-03-17 (bug 819819). See member function version for workaround
        }
    };

    int main()
    {
        stack<int> s;
        s.push(1);
        s.push(2);
        s.push(3);
    }

### See also

compare_exchange_weak compare_exchange_strong | atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not (public member function of `std::atomic`)
atomic_exchange atomic_exchange_explicit (C++11)(C++11) | atomically replaces the value of the atomic object with non-atomic argument and returns the old value of the atomic (function template)
std::atomic_compare_exchange_weak(std::shared_ptr) std::atomic_compare_exchange_strong(std::shared_ptr) | specializes atomic operations for std::shared_ptr (function template)
C documentation for atomic_compare_exchange, atomic_compare_exchange_explicit

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/atomic/atomic_compare_exchange&oldid=91369"
Category:

- unconditionally noexcept

Hidden categories:

- Pages with unreviewed unconditional noexcept template
- Pages with unreviewed noexcept template