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

4506. source_location is explicitly unspecified if is constexpr or not

Section: 17.8.2 [support.srcloc.class] Status: Immediate Submitter: Hana Dusíková Opened: 2025-12-27 Last modified: 2026-03-27

Priority: 2

View all issues with Immediate status.

Discussion:

Basically in 17.8.2.1 [support.srcloc.class.general] following p1 there is a note from Jens from six years ago which says (emphasis mine):

[Note 1: The intent of source_location is to have a small size and efficient copying. It is unspecified whether the copy/move constructors and the copy/move assignment operators are trivial and/or constexpr. — end note]

But also reflection's std::meta::source_location_of returns it by value and is consteval. This means source_location needs to be specified to constexpr. And good news is ... all three major implementations have it constexpr implicitly.

Options are (from my perspective) to remove that part of the note "and/or constexpr" and just call it a day, or add

constexpr source_location(const source_location&) = default;
constexpr source_location(source_location&&) noexcept = default;
constexpr source_location& operator=(const source_location&) = default;
constexpr source_location& operator=(source_location&&) noexcept = default;

AFAIK this is how to explicitly say it must be constexpr but it can still be trivial, see demo.

[2026-02-18; Reflector poll.]

Set priority to 2 after reflector poll.

[2026-03-26; Tim adds wording]

[Croydon 2026-03-27; move to Immediate.]

Proposed resolution:

This wording is relative to N5032.

[Drafting note: 16.3.3.5 [functions.within.classes] can be read to say that the functions are constexpr already, but given the note that contradicts this interpretion, explicit declarations can't hurt. — end drafting note]

  1. Modify 17.8.2.1 [support.srcloc.class.general] as indicated:

    namespace std {
      struct source_location {
        // source location construction
        static consteval source_location current() noexcept;
        constexpr source_location() noexcept;
    
        constexpr source_location(const source_location&) noexcept = default;
        constexpr source_location& operator=(const source_location&) noexcept = default;
    
        // source location field access
        constexpr uint_least32_t line() const noexcept;
        constexpr uint_least32_t column() const noexcept;
        constexpr const char* file_name() const noexcept;
        constexpr const char* function_name() const noexcept;
    
      private:
        uint_least32_t line_;               // exposition only
        uint_least32_t column_;             // exposition only
        const char* file_name_;             // exposition only
        const char* function_name_;         // exposition only
      };
    }
    

    - 1- The type source_location meets the Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable, Cpp17Swappable, and Cpp17Destructible requirements (16.4.4.2 [utility.arg.requirements], 16.4.4.3 [swappable.requirements]) models semiregular. is_nothrow_swappable_v<source_location> is true. All of the following conditions are true:

    1. (1.1) — is_nothrow_move_constructible_v<source_location>

    2. (1.2) — is_nothrow_move_assignable_v<source_location>

    3. (1.3) — is_nothrow_swappable_v<source_location>

    [Note 1: The intent of source_location is to have a small size and efficient copying. It is unspecified whether the copy/move constructors and the copy/move assignment operators are trivial and/or constexpr. — end note]