[atomics.types.pointer]

# 32 Concurrency support library [[thread]](./#thread)

## 32.5 Atomic operations [[atomics]](atomics#types.pointer)

### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#atomics.types.pointer)

#### 32.5.8.5 Partial specialization for pointers [atomics.types.pointer]

namespace std {template<class T> struct atomic<T*> {using value_type = T*; using difference_type = ptrdiff_t; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(T*) noexcept;
 atomic(const atomic&) = delete;
 atomic& operator=(const atomic&) = delete;
 atomic& operator=(const atomic&) volatile = delete; void store(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store(T*, memory_order = memory_order::seq_cst) noexcept;
 T* operator=(T*) volatile noexcept; constexpr T* operator=(T*) noexcept;
 T* load(memory_order = memory_order::seq_cst) const volatile noexcept; constexpr T* load(memory_order = memory_order::seq_cst) const noexcept; operator T*() const volatile noexcept; constexpr operator T*() const noexcept;

 T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* exchange(T*, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept; bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept; bool compare_exchange_weak(T*&, T*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(T*&, T*,
 memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(T*&, T*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_strong(T*&, T*,
 memory_order = memory_order::seq_cst) noexcept;

 T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
 T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
 T* fetch_max(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_max(T*, memory_order = memory_order::seq_cst) noexcept;
 T* fetch_min(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept; void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept; void store_max(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_max(T*, memory_order = memory_order::seq_cst) noexcept; void store_min(T*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_min(T*, memory_order = memory_order::seq_cst) noexcept;

 T* operator++(int) volatile noexcept; constexpr T* operator++(int) noexcept;
 T* operator--(int) volatile noexcept; constexpr T* operator--(int) noexcept;
 T* operator++() volatile noexcept; constexpr T* operator++() noexcept;
 T* operator--() volatile noexcept; constexpr T* operator--() noexcept;
 T* operator+=(ptrdiff_t) volatile noexcept; constexpr T* operator+=(ptrdiff_t) noexcept;
 T* operator-=(ptrdiff_t) volatile noexcept; constexpr T* operator-=(ptrdiff_t) noexcept; void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; constexpr void wait(T*, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; constexpr void notify_one() noexcept; void notify_all() volatile noexcept; constexpr void notify_all() noexcept; };}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5825)

There is a partial specialization of the atomic class template for pointers[.](#1.sentence-1)

Specializations of this partial specialization are standard-layout structs[.](#1.sentence-2)

They each have a trivial destructor[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5830)

Descriptions are provided below only for members that differ from the primary template[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5833)

The following operations perform pointer arithmetic[.](#3.sentence-1)

The correspondence among key, operator, and computation is specified
in Table [156](#tab:atomic.types.pointer.comp "Table 156: Atomic pointer computations")[.](#3.sentence-2)

Table [156](#tab:atomic.types.pointer.comp) — Atomic pointer computations [[tab:atomic.types.pointer.comp]](./tab:atomic.types.pointer.comp)  

| [ð](#tab:atomic.types.pointer.comp-row-1)<br>***key*** | **Op** | **Computation** | ***key*** | **Op** | **Computation** |
| --- | --- | --- | --- | --- | --- |
| [ð](#tab:atomic.types.pointer.comp-row-2)<br>add | + | addition | sub | - | subtraction |
| [ð](#tab:atomic.types.pointer.comp-row-3)<br>max |  | maximum | min |  | minimum |

[ð](#lib:atomic_fetch_add)

`T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept;
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5879)

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5884)

*Mandates*: T is a complete object type[.](#5.sentence-1)

[*Note [1](#note-1)*:

Pointer arithmetic on void* or function pointers is ill-formed[.](#5.sentence-2)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5891)

*Effects*: Atomically replaces the value pointed to bythis with the result of the computation applied to the
value pointed to by this and the given operand[.](#6.sentence-1)

Memory is affected according to the value of order[.](#6.sentence-2)

These operations are atomic read-modify-write operations ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#6.sentence-3)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5899)

*Returns*: Atomically, the value pointed to by this immediately before the effects[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5903)

*Remarks*: The result may be an undefined address,
but the operations otherwise have no undefined behavior[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5908)

For fetch_max and fetch_min, the maximum and minimum
computation is performed as if by max and min algorithms ([[alg.min.max]](alg.min.max "26.8.9 Minimum and maximum")), respectively, with the object value and the first
parameter as the arguments[.](#9.sentence-1)

[*Note [2](#note-2)*:

If the pointers point to different complete objects (or subobjects thereof),
the < operator does not establish a strict weak ordering
(Table [29](utility.arg.requirements#tab:cpp17.lessthancomparable "Table 29: Cpp17LessThanComparable requirements"), [[expr.rel]](expr.rel "7.6.9 Relational operators"))[.](#9.sentence-2)

â *end note*]

[ð](#lib:atomic_store_add)

`void store_key(see above operand, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store_key(see above operand, memory_order order = memory_order::seq_cst) noexcept;
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5939)

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5944)

*Mandates*: T is a complete object type[.](#11.sentence-1)

[*Note [3](#note-3)*:

Pointer arithmetic on void* or function pointers is ill-formed[.](#11.sentence-2)

â *end note*]

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5951)

*Effects*: Atomically replaces the value pointed to by this with the result of the computation applied to
the value pointed to by this and the given operand[.](#12.sentence-1)

Memory is affected according to the value of order[.](#12.sentence-2)

These operations are atomic modify-write operations ([[atomics.order]](atomics.order "32.5.4 Order and consistency"))[.](#12.sentence-3)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5959)

*Remarks*: The result may be an undefined address,
but the operations otherwise have no undefined behavior[.](#13.sentence-1)

For store_max and store_min,
the maximum and minimum computation is performed
as if by max and min algorithms ([[alg.min.max]](alg.min.max "26.8.9 Minimum and maximum")), respectively,
with the value pointed to by this and
the first parameter as the arguments[.](#13.sentence-2)

[*Note [4](#note-4)*:

If the pointers point to different complete objects (or subobjects thereof),
the < operator does not establish
a strict weak ordering (Table [29](utility.arg.requirements#tab:cpp17.lessthancomparable "Table 29: Cpp17LessThanComparable requirements"), [[expr.rel]](expr.rel "7.6.9 Relational operators"))[.](#13.sentence-3)

â *end note*]

[ð](#lib:operator+=,atomic%3cT*%3e)

`T* operator op=(ptrdiff_t operand) volatile noexcept;
constexpr T* operator op=(ptrdiff_t operand) noexcept;
`

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5983)

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#14.sentence-1)

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L5988)

*Effects*: Equivalent to: return fetch_*key*(operand) *op* operand;
