Title
std::atomic<T>'s default constructor should be constrained
Status
wp
Section
[atomics.types.operations]
Submitter
Giuseppe D'Angelo

Created on 2024-10-15.00:00:00 last changed 3 weeks ago

Messages

Date: 2024-11-28.21:40:31

Proposed resolution:

This wording is relative to N4993.

  1. Modify [atomics.types.operations] as indicated:

    [Drafting note: There is implementation divergence at the moment; libstdc++ already implements the proposed resolution and has done so for a while.]

    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
    

    -1- ConstraintsMandates: is_default_constructible_v<T> is true.

    -2- Effects: […]

Date: 2024-11-28.21:40:31

[ Wrocław 2024-11-23; Status changed: Voting → WP. ]

Date: 2024-11-15.00:00:00

[ 2024-11-13; Reflector poll ]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

Date: 2024-10-15.00:00:00

The current wording for `std::atomic`'s default constructor in [atomics.types.operations] specifies:

constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);

Mandates: is_default_constructible_v<T> is true.

This wording has been added by P0883R2 for C++20, which changed `std::atomic`'s default constructor to always value-initialize. Before, the behavior of this constructor was not well specified (this was LWG issue 2334).

The usage of a Mandates element in the specification has as a consequence that std::atomic<T> is always default constructible, even when T is not. For instance:

// not default constructible:
struct NDC { NDC(int) {} };

static_assert(std::is_default_constructible<std::atomic<NDC>>); // OK

The above check is OK as per language rules, but this is user-hostile: actually using std::atomic<NDC>'s default constructor results in an error, despite the detection saying otherwise.

Given that std::atomic<T> already requires T to be complete anyhow ([atomics.types.generic.general] checks for various type properties which require completeness) it would be more appropriate to use a constraint instead, so that std::atomic<T> is default constructible if and only if T also is.

History
Date User Action Args
2024-11-28 21:40:31adminsetmessages: + msg14499
2024-11-28 21:40:31adminsetstatus: voting -> wp
2024-11-19 16:09:07adminsetstatus: ready -> voting
2024-11-13 20:38:33adminsetmessages: + msg14451
2024-11-13 20:38:33adminsetstatus: new -> ready
2024-10-31 07:29:54adminsetmessages: + msg14444
2024-10-15 00:00:00admincreate