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

3999. P0439R0 changed the value category of memory order constants

Section: 32.5.4 [atomics.order] Status: NAD Submitter: Jiang An Opened: 2023-10-18 Last modified: 2026-08-21

Priority: 4

View other active issues in [atomics.order].

View all other issues in [atomics.order].

View all issues with NAD status.

Discussion:

P0439R0 made std::memory_order an scoped enumeration type. However, it also changed former enumerators (std::memory_order_seq_cst) to constexpr variables.

It is unclear the additional change is intended while it presumably bothered nobody in practice. Given there is using enum (P1099R5) in C++20, it may be better to keep these constants being prvalues.

[2023-11-02; Reflector poll]

Set priority to 4 after reflector poll.

[2026-08-21 LWG telecon; Status changed New → NAD]

The proposed resolution would need to be rebased because consume has been deprecated now.

Although LWG liked the first part of the change, making the old names enumerators again rather than global objects, we did not like the second part which adds new enumerators with the old names. The cure seems worse than the disease. Having the old names be objects that can have their address taken (and can have references bound directly to them without creating a temporary) is a little unpleasant, but it doesn't really do any harm. If you want to ensure that no inline variables get emitted into your object files when you refer to those memory orders, just use the new form, i.e. the memory_order::seq_cst names instead of memory_order_seq_cst.

If we had a feature like using memory_order::seq_cst as memory_order_seq_cst which would allow giving a new name to the enumerator, it could be done without having to add the new enumerators to the enum.

From an implementation perspective, using enum is a C++20 feature so would require compiler extensions to make it available in C++17 modes, or the defect would still be present in C++17 modes and only fixed for C++20 and later.

Proposed resolution:

This wording is relative to N4964.

  1. Modify 32.5.2 [atomics.syn], header <atomic> synopsis, as indicated:

    namespace std {
      // 32.5.4 [atomics.order], order and consistency
      enum class memory_order : unspecified;                        // freestanding
      inline constexpr memory_order memory_order_relaxed = memory_order::relaxedusing memory_order::memory_order_relaxed; // freestanding
      inline constexpr memory_order memory_order_consume = memory_order::consumeusing memory_order::memory_order_consume; // freestanding
      inline constexpr memory_order memory_order_acquire = memory_order::acquireusing memory_order::memory_order_acquire; // freestanding
      inline constexpr memory_order memory_order_release = memory_order::releaseusing memory_order::memory_order_release; // freestanding
      inline constexpr memory_order memory_order_acq_rel = memory_order::acq_relusing memory_order::memory_order_acq_rel; // freestanding
      inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cstusing memory_order::memory_order_seq_cst; // freestanding
      
      […]
    }
    […]
    
  2. Modify 32.5.4 [atomics.order] as indicated:

    namespace std {
      enum class memory_order : unspecified {
        relaxed, consume, acquire, release, acq_rel, seq_cst,
        memory_order_relaxed = relaxed, memory_order_consume = consume, memory_order_acquire = acquire,
        memory_order_release = release, memory_order_acq_rel = acq_rel, memory_order_seq_cst = seq_cst
      };
    }