std::atomic_compare_exchange_weak, std::atomic_compare_exchange_strong, std::atomic_compare_exchange_weak_explicit, std::atomic_compare_exchange_strong_explicit - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# 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 value pointed to by `obj` with the value pointed to by `expected`, and if those are 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).

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.

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.

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)

### [edit] 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`

### [edit] Return value

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

### [edit] Exceptions

`noexcept` specification:
noexcept

### [edit] 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
            node<T>* old_head = (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
                                                             , &old_head
                                                             , new_node
                                                             , std::memory_order_release
                                                             , std::memory_order_relaxed))
            {
                new_node->next = old_head;
            }
        }
    };

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

### [edit] See also

compare_exchange_weakcompare_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`) [edit]
atomic_exchangeatomic_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) [edit]
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=67640"
Category:

- unconditionally noexcept