This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
Section: 33.5 [atomics] Status: New Submitter: Wesley Maxey Opened: 2021-11-05 Last modified: 2022-01-29
Priority: 3
View all other issues in [atomics].
View all issues with New status.
Discussion:
The specification of atomic and atomic<T*> (in 33.5.8.1 [atomics.types.generic.general] and 33.5.8.5 [atomics.types.pointer]) explicitly deletes the following functions:
atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete;
The intent is to make atomic objects not copyable, so that initializing an atomic object from another atomic, or assigning an atomic object with a value from another atomic, must be an explicit operation.
We also explicitly support volatile objects of types that are specializations of std::atomic; some of the functions that are vital for the support of volatile atomics are the following conversion operators:operator T() const volatile noexcept; // for non-pointers operator T*() const volatile noexcept; // for pointers
The presence of this conversion operator means that all the statements in the following piece of code compile successfully today, despite the deleted functions mentioned earlier:
volatile std::atomic<int> a; volatile std::atomic<int> b(a); std::atomic<int> c(a); b = a; c = a;
However, if a is not a volatile object, none of the last four lines compile.
[2022-01-29; Reflector poll]
Set priority to 3 after reflector poll.
This PR would allow
atomic<int> x, y = std::move(x);because const volatile& doesn't bind to rvalues. It sounds like we'll need to delete both const volatile& and const volatile&&.
Proposed resolution:
This wording is relative to N4901.
Modify 33.5.8.1 [atomics.types.generic.general], class template atomic synopsis, as indicated:
[…] atomic(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) volatile = delete; […]
Modify 33.5.8.3 [atomics.types.int], class template atomic<integral> specialization synopsis, as indicated:
[…] atomic(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) volatile = delete; […]
Modify 33.5.8.4 [atomics.types.float], class template atomic<floating-point> specialization synopsis, as indicated:
[…] atomic(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) volatile = delete; […]
Modify 33.5.8.5 [atomics.types.pointer], class template atomic<T*> partial specialization synopsis, as indicated:
[…] atomic(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) = delete; atomic& operator=(const volatile atomic&) volatile = delete; […]