std::atomic::compare_exchange_weak, std::atomic::compare_exchange_strong - 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

From cppreference.com
< cpp‎ | atomic‎ | atomic

Defined in header `<atomic>` |  |

| (1) | (since C++11)
bool compare_exchange_weak( T& expected, T desired, std::memory_order success, std::memory_order failure ); |  |
bool compare_exchange_weak( T& expected, T desired, std::memory_order success, std::memory_order failure ) volatile; |  |
| (2) | (since C++11)
bool compare_exchange_weak( T& expected, T desired, std::memory_order order = std::memory_order_seq_cst ); |  |
bool compare_exchange_weak( T& expected, T desired, std::memory_order order = std::memory_order_seq_cst ) volatile; |  |
| (3) | (since C++11)
bool compare_exchange_strong( T& expected, T desired, std::memory_order success, std::memory_order failure ); |  |
bool compare_exchange_strong( T& expected, T desired, std::memory_order success, std::memory_order failure ) volatile; |  |
| (4) | (since C++11)
bool compare_exchange_strong( T& expected, T desired, std::memory_order order = std::memory_order_seq_cst ); |  |
bool compare_exchange_strong( T& expected, T desired, std::memory_order order = std::memory_order_seq_cst ) volatile; |  |

Atomically compares the value stored in `*this` with the value of `expected`, and if those are equal, replaces the former with `desired` (performs read-modify-write operation). Otherwise, loads the actual value stored in `*this` into `expected` (performs load operation).

The memory models for the read-modify-write and load operations are `success` and `failure` respectively. In the (2) and (4) versions `order` is used for both read-modify-write and load operations, except that std::memory_order_acquire and std::memory_order_relaxed are used for the load operation if order == std::memory_order_acq_rel, or order == std::memory_order_release respectively.

The weak forms (1-2) of the functions are allowed to fail spuriously, that is, act as if *this != 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.

### [edit] Parameters

expected | - | reference 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
success | - | the memory synchronization ordering for the read-modify-write operation if the comparison succeeds. All values are permitted.
failure | - | 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 `success`
order | - | the memory synchronization ordering for both operations

### [edit] Return value

true if the underlying atomic value was changed, 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<typename T>
    struct node
    {
        T data;
        node* next;
        node(const T& data) : data(data), next(nullptr) {}
    };

    template<typename 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(!head.compare_exchange_weak(new_node->next, new_node,
    //                                        std::memory_order_release,
    //                                        std::memory_order_relaxed))
    //          ; // the body of the loop is empty
    //
    // Note: the above use is not thread-safe in at least
    // GCC prior to 4.8.3 (bug 60272), clang (bug 18899), MSVC (bug 819819).
    // The following is a workaround:
            node<T>* old_head = head.load(std::memory_order_relaxed);
            do {
                new_node->next = old_head;
            } while(!head.compare_exchange_weak(old_head, new_node,
                                                std::memory_order_release,
                                                std::memory_order_relaxed));
        }
    };
    int main()
    {
        stack<int> s;
        s.push(1);
        s.push(2);
        s.push(3);
    }

Demonstrates how compare_exchange_strong either changes the value of the atomic variable or the variable used for comparison.

Run this code

    #include <atomic>
    #include <iostream>

    std::atomic<int>  ai;

    int  tst_val= 4;
    int  new_val= 5;
    bool exchanged= false;

    void valsout()
    {
        std::cout << "ai= " << ai
    	      << "  tst_val= " << tst_val
    	      << "  new_val= " << new_val
    	      << "  exchanged= " << std::boolalpha << exchanged
    	      << "\n";
    }

    int main()
    {
        ai= 3;
        valsout();

        // tst_val != ai   ==>  tst_val is modified
        exchanged= ai.compare_exchange_strong( tst_val, new_val );
        valsout();

        // tst_val == ai   ==>  ai is modified
        exchanged= ai.compare_exchange_strong( tst_val, new_val );
        valsout();

        return 0;
    }

Output:

    ai= 3  tst_val= 4  new_val= 5  exchanged= false
    ai= 3  tst_val= 3  new_val= 5  exchanged= false
    ai= 5  tst_val= 3  new_val= 5  exchanged= true

### [edit] See also

atomic_compare_exchange_weakatomic_compare_exchange_weak_explicitatomic_compare_exchange_strongatomic_compare_exchange_strong_explicit (C++11)(C++11)(C++11)(C++11) | atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not (function template) [edit]

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

- unconditionally noexcept