Title
Atomics are copy constructible and copy assignable from volatile atomics
Status
new
Section
[atomics]
Submitter
Wesley Maxey

Created on 2021-11-05.00:00:00 last changed 34 months ago

Messages

Date: 2022-01-29.22:29:35

Proposed resolution:

This wording is relative to N4901.

  1. Modify [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;
    […]
    
  2. Modify [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;
    […]
    
  3. Modify [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;
    […]
    
  4. Modify [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;
    […]
    
Date: 2022-01-15.00:00:00

[ 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&&.

Date: 2021-11-05.00:00:00

The specification of atomic and atomic<T*> (in [atomics.types.generic.general] and [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.

History
Date User Action Args
2022-01-29 22:29:35adminsetmessages: + msg12300
2021-11-06 16:38:04adminsetmessages: + msg12211
2021-11-05 00:00:00admincreate