Title
make_error_code and make_error_condition are customization points
Status
c++23
Section
[syserr]
Submitter
Jonathan Wakely

Created on 2021-10-31.00:00:00 last changed 12 months ago

Messages

Date: 2022-11-17.00:42:33

Proposed resolution:

This wording is relative to N4910.

  • Modify [contents] as indicated:

    -3- Whenever an unqualified name other than swap, make_error_code, or make_error_condition is used in the specification of a declaration D in [support] through [thread] or [depr], its meaning is established as-if by performing unqualified name lookup ([basic.lookup.unqual]) in the context of D.

    [Note 1: Argument-dependent lookup is not performed. — end note]

    Similarly, the meaning of a qualified-id is established as-if by performing qualified name lookup ([basic.lookup.qual]) in the context of D.

    [Example 1: The reference to is_array_v in the specification of std::to_array ([array.creation]) refers to ::std::is_array_v. — end example]

    [Note 2: Operators in expressions ([over.match.oper]) are not so constrained; see [global.functions]. — end note]

    The meaning of the unqualified name swap is established in an overload resolution context for swappable values ([swappable.requirements]). The meanings of the unqualified names make_error_code and make_error_condition are established as-if by performing argument-dependent lookup ([basic.lookup.argdep]).

  • Modify [syserr.errcode.constructors] as indicated:

    error_code() noexcept;

    -1- Postconditions: val_ == 0 and cat_ == &system_category().
    -1- Effects: Initializes val_ with 0 and cat_ with &system_category().

    error_code(int val, const error_category& cat) noexcept;

    -2- Postconditions: val_ == val and cat_ == &cat.
    -2- Effects: Initializes val_ with val and cat_ with &cat.

    template<class ErrorCodeEnum>
      error_code(ErrorCodeEnum e) noexcept;

    -3- Constraints: is_error_code_enum_v<ErrorCodeEnum> is true.

    -4- Postconditions: *this == make_error_code(e).
    -4- Effects: Equivalent to:

    error_code ec = make_error_code(e);
    assign(ec.value(), ec.category());
    

  • Modify [syserr.errcode.modifiers] as indicated:

    template<class ErrorCodeEnum>
      error_code& operator=(ErrorCodeEnum e) noexcept;

    -2- Constraints: is_error_code_enum_v<ErrorCodeEnum> is true.

    -3- Postconditions: *this == make_error_code(e).
    -3- Effects: Equivalent to:

    error_code ec = make_error_code(e);
    assign(ec.value(), ec.category());
    

    -4- Returns: *this.

  • Modify [syserr.errcondition.constructors] as indicated:

    error_condition() noexcept;

    -1- Postconditions: val_ == 0 and cat_ == &generic_category().
    -1- Effects: Initializes val_ with 0 and cat_ with &generic_category().

    error_condition(int val, const error_category& cat) noexcept;

    -2- Postconditions: val_ == val and cat_ == &cat.
    -2- Effects: Initializes val_ with val and cat_ with &cat.

    template<class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e) noexcept;

    -3- Constraints: is_error_condition_enum_v<ErrorConditionEnum> is true.

    -4- Postconditions: *this == make_error_condition(e).
    -4- Effects: Equivalent to:

    error_condition ec = make_error_condition(e);
    assign(ec.value(), ec.category());
    

  • Modify [syserr.errcondition.modifiers] as indicated:

    template<class ErrorConditionEnum>
      error_condition& operator=(ErrorConditionEnum e) noexcept;

    -2- Constraints: is_error_condition_enum_v<ErrorConditionEnum> is true.

    -3- Postconditions: *this == make_error_condition(e).
    -3- Effects: Equivalent to:

    error_condition ec = make_error_condition(e);
    assign(ec.value(), ec.category());
    

    -4- Returns: *this.

Date: 2022-11-12.00:00:00

[ 2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP. ]

Date: 2022-09-15.00:00:00

[ 2022-09-23; Reflector poll ]

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

Date: 2022-09-15.00:00:00

[ 2022-09-07; Jonathan Wakely revises wording ]

Discussed in LWG telecon. Decided to change "established as-if by performing unqualified name lookup and argument-dependent lookup" to simply "established as-if by performing argument-dependent lookup".

This resolves the question of whether std::make_error_code(errc), std::make_error_code(io_errc), etc. should be visible to the unqualified name lookup. This affects whether a program-defined type that specializes is_error_code_enum but doesn't provide an overload of make_error_code should find the overloads in namespace std and consider them for overload resolution, via implicit conversion to std::errc, std::io_errc, etc.

Date: 2022-08-25.19:11:49

[ 2022-08-25; Jonathan Wakely provides improved wording ]

Discussed in LWG telecon and decided on new direction:

  • Add make_error_code and make_error_condition to [contents] as done for swap. Describe form of lookup used for them.
  • Respecify error_code and error_condition constructors in terms of "Effects: Equivalent to" so that the requirements on program-defined overloads found by ADL are implied by those effects.

Date: 2022-01-15.00:00:00

[ 2022-01-29; Reflector poll ]

Set priority to 2 after reflector poll.

Previous resolution [SUPERSEDED]:

This wording is relative to N4901.

  1. Modify [system.error.syn] as indicated:

    -1- The value of each enum errc constant shall be the same as the value of the <cerrno> macro shown in the above synopsis. Whether or not the <system_error> implementation exposes the <cerrno> macros is unspecified.

    -?- Invocations of make_error_code and make_error_condition shown in subclause [syserr] select a function to call via overload resolution ([over.match]) on a candidate set that includes the lookup set found by argument dependent lookup ([basic.lookup.argdep]).

    -2- The is_error_code_enum and is_error_condition_enum templates may be specialized for program-defined types to indicate that such types are eligible for class error_code and class error_condition implicit conversions, respectively.

    [Note 1: Conversions from such types are done by program-defined overloads of make_error_code and make_error_condition, found by ADL. —end note]

Date: 2021-10-31.00:00:00

The rule in [contents] means that the calls to make_error_code in [syserr.errcode.constructors] and [syserr.errcode.modifiers] are required to call std::make_error_code, which means program-defined error codes do not work. The same applies to the make_error_condition calls in [syserr.errcondition.constructors] and [syserr.errcondition.modifiers].

They need to use ADL. This is what all known implementations (including Boost.System) do.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2022-11-17 00:42:33adminsetmessages: + msg13050
2022-11-17 00:42:33adminsetstatus: voting -> wp
2022-11-08 03:46:49adminsetstatus: ready -> voting
2022-09-23 15:43:32adminsetmessages: + msg12795
2022-09-23 15:43:32adminsetstatus: open -> ready
2022-09-07 19:24:28adminsetmessages: + msg12748
2022-08-25 19:38:16adminsetstatus: new -> open
2022-08-25 19:11:49adminsetmessages: + msg12713
2022-01-29 22:29:35adminsetmessages: + msg12297
2021-10-31 18:56:02adminsetmessages: + msg12203
2021-10-31 00:00:00admincreate