# std::atomic<T>::operator++,++(int),--,--(int)

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

T operator++() noexcept; T operator++() volatile noexcept; | (1) | (member only of `atomic<Integral>` template specialization) (since C++11)
T* operator++() noexcept; T* operator++() volatile noexcept; | (1) | (member only of `atomic<T*>` template specialization) (since C++11)
T operator++( int ) noexcept; T operator++( int ) volatile noexcept; | (2) | (member only of `atomic<Integral>` template specialization) (since C++11)
T* operator++( int ) noexcept; T* operator++( int ) volatile noexcept; | (2) | (member only of `atomic<T*>` template specialization) (since C++11)
T operator--() noexcept; T operator--() volatile noexcept; | (3) | (member only of `atomic<Integral>` template specialization) (since C++11)
T* operator--() noexcept; T* operator--() volatile noexcept; | (3) | (member only of `atomic<T*>` template specialization) (since C++11)
T operator--( int ) noexcept; T operator--( int ) volatile noexcept; | (4) | (member only of `atomic<Integral>` template specialization) (since C++11)
T* operator--( int ) noexcept; T* operator--( int ) volatile noexcept; | (4) | (member only of `atomic<T*>` template specialization) (since C++11)

Atomically increments or decrements the current value. The operation is read-modify-write operation.

1) Performs atomic pre-increment. Equivalent to fetch_add(1)+1.
2) Performs atomic post-increment. Equivalent to fetch_add(1).
3) Performs atomic pre-decrement. Equivalent to fetch_sub(1)-1
4) Performs atomic post-decrement. Equivalent to fetch_sub(1).

For signed `Integral` types, arithmetic is defined to use two’s complement representation. There are no undefined results.

For `T*` types, the result may be an undefined address, but the operations otherwise have no undefined behavior. The program is ill-formed if `T` is not an object type.

The volatile-qualified versions are deprecated if std::atomic<T>::is_always_lock_free is false. | (since C++20)

### Parameters

(none)

### Return value

1,3) The value of the atomic variable after the modification. Formally, the result of incrementing/decrementing the value immediately preceding the effects of this function in the modification order of `*this`.
2,4) The value of the atomic variable before the modification. Formally, the value immediately preceding the effects of this function in the modification order of `*this`.

### Notes

Unlike most pre-increment and pre-decrement operators, the pre-increment and pre-decrement operators for atomic types do not return a reference to the modified object. They return a copy of the stored value instead.

### Example

Run this code

    #include <atomic>
    #include <chrono>
    #include <iomanip>
    #include <iostream>
    #include <mutex>
    #include <random>
    #include <thread>

    std::atomic<int> atomic_count{0};
    std::atomic<int> atomic_writes{0};

    constexpr int global_max_count{72};
    constexpr int writes_per_line{8};
    constexpr int max_delay{100};

    template<int Max> int random_value()
    {
        static std::uniform_int_distribution<int> distr{1, Max};
        static std::random_device engine;
        static std::mt19937 noise{engine()};
        static std::mutex rand_mutex;
        std::lock_guard μ{rand_mutex};
        return distr(noise);
    }

    int main()
    {
        auto work = [](const char id)
        {
            for (int count{}; (count = ++atomic_count) <= global_max_count;) {
                std::this_thread::sleep_for(
                    std::chrono::milliseconds(random_value<max_delay>()));

                bool new_line{false};
                if (++atomic_writes % writes_per_line == 0) {
                    new_line = true;
                }
                // print thread `id` and `count` value
                {
                    static std::mutex cout_mutex;
                    std::lock_guard m{cout_mutex};
                    std::cout << "[" << id << "] " << std::setw(3) << count << " │ "
                              << (new_line ? "\n" : "") << std::flush;
                }
            }
        };

        std::jthread j1(work, 'A'), j2(work, 'B'), j3(work, 'C'), j4(work, 'D');
    }

Possible output:

    [B]   3 │ [D]   1 │ [C]   2 │ [D]   6 │ [A]   4 │ [B]   5 │ [B]  10 │ [D]   8 │
    [C]   7 │ [A]   9 │ [A]  14 │ [B]  11 │ [D]  12 │ [C]  13 │ [A]  15 │ [C]  18 │
    [D]  17 │ [B]  16 │ [C]  20 │ [C]  23 │ [D]  21 │ [A]  19 │ [C]  24 │ [B]  22 │
    [A]  26 │ [C]  27 │ [D]  25 │ [C]  30 │ [B]  28 │ [D]  31 │ [A]  29 │ [C]  32 │
    [B]  33 │ [D]  34 │ [B]  37 │ [B]  39 │ [B]  40 │ [A]  35 │ [C]  36 │ [C]  43 │
    [D]  38 │ [A]  42 │ [B]  41 │ [A]  46 │ [B]  47 │ [C]  44 │ [A]  48 │ [D]  45 │
    [C]  50 │ [D]  52 │ [B]  49 │ [D]  54 │ [C]  53 │ [A]  51 │ [B]  55 │ [D]  56 │
    [D]  60 │ [A]  58 │ [C]  57 │ [D]  61 │ [C]  63 │ [B]  59 │ [D]  64 │ [C]  65 │
    [A]  62 │ [D]  67 │ [B]  66 │ [C]  68 │ [D]  70 │ [C]  72 │ [B]  71 │ [A]  69 │

### Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior
--- | --- | --- | ---
P0558R1 | C++11 | arithmetic permitted on pointers to cv void or function | made ill-formed

### See also

fetch_add | atomically adds the argument to the value stored in the atomic object and obtains the value held previously (public member function)
fetch_sub | atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously (public member function)
operator+=operator-=operator&=operator|=operator^= | adds, subtracts, or performs bitwise AND, OR, XOR with the atomic value (public member function)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/atomic/atomic/operator_arith&oldid=127461"