This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3012. `atomic<T>` is unimplementable for non-`is_trivially_copy_constructible T`

Section: 31.8 [atomics.types.generic] Status: C++20 Submitter: Billy O'Neal III Opened: 2017-08-16 Last modified: 2021-02-25

Priority: 2

View all other issues in [atomics.types.generic].

View all issues with C++20 status.

Discussion:

31.8 [atomics.types.generic] requires that `T` for `std::atomic` is trivially copyable. Unfortunately, that's not sufficient to implement `atomic`. Consider `atomic<T>::load`, which wants to look something like this:

>     template<class T>
>     struct atomic {
>       __compiler_magic_storage_for_t storage;

>       T load(memory_order = memory_order_seq_cst) const {
>         return __magic_intrinsic(storage);
>       }

>     };

Forming this return statement, though, requires that `T` is copy constructible — trivially copyable things aren't necessarily copyable! For example, the following is trivially copyable but breaks libc++, libstdc++, and msvc++:

>     struct NonAssignable {
>       int i;
>       NonAssignable() = delete;
>       NonAssignable(int) : i(0) {}
>       NonAssignable(const NonAssignable&) = delete;
>       NonAssignable(NonAssignable&&) = default;
>       NonAssignable& operator=(const NonAssignable&) = delete;
>       NonAssignable& operator=(NonAssignable&&) = delete;
>       ~NonAssignable() = default;
>     };

All three standard libraries are happy as long as `T` is trivially copy constructible, assignability is not required. Casey Carter says that we might want to still require trivially copy assignable though, since what happens when you do an `atomic<T>::store` is morally an "assignment" even if it doesn't use the user's assignment operator.

[2017-11 Albuquerque Wednesday issue processing]

Status to Open; Casey and STL to work with Billy for better wording.

Should this include trivially copyable as well as trivially copy assignable?

2017-11-09, Billy O'Neal provides updated wording.

Previous resolution [SUPERSEDED]:

> This resolution is relative to N4687.

> 1. Edit 31.8 [atomics.types.generic] as indicated:

>    > -1- If `is_trivially_copy_constructible_v<T>` is `false`, the program is ill-formed The template argument for `T` shall be trivially copyable (6.8 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]

Previous resolution [SUPERSEDED]:

> This resolution is relative to N4687.

> 1. Edit 31.8 [atomics.types.generic] as indicated:

>    > -1- If `is_copy_constructible_v<T>` is `false` or if `is_trivially_copyable_v<T>` is `false`, the program is ill-formed The template argument for `T` shall be trivially copyable (6.8 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]

[2017-11-12, Tomasz comments and suggests alternative wording]

According to my understanding during Albuquerque Saturday issue processing we agreed that we want the type used with the atomics to have non-deleted and trivial copy/move construction and assignment.

Wording note: `CopyConstructible` and `CopyAssignable` include semantic requirements that are not checkable at compile time, so these are requirements imposed on the user and cannot be validated by an implementation without heroic efforts.

[2018-11 San Diego Thursday night issue processing]

Status to Ready.

Proposed resolution:

This resolution is relative to N4700.

1. Edit 31.8 [atomics.types.generic] as indicated:

   > -1- The template argument for `T` shall meet the `CopyConstructible` and `CopyAssignable` requirements. If `is_trivially_copyable_v<T> && is_copy_constructible_v<T> && is_move_constructible_v<T> && is_copy_assignable_v<T> && is_move_assignable_v<T>` is `false`, the program is ill-formed be trivially copyable (6.8 [basic.types]). [Note: Type arguments that are not also statically initializable may be difficult to use. — end note]