22 Diagnostics library [diagnostics]

22.5 System error support [syserr]

This subclause describes components that the standard library and C++ programs may use to report error conditions originating from the operating system or other low-level application program interfaces.
Components described in this subclause shall not change the value of errno.
Implementations should leave the error states provided by other libraries unchanged.

22.5.1 Header <system_­error> synopsis [system_error.syn]

namespace std {
  class error_category;
  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;

  class error_code;
  class error_condition;
  class system_error;

  template <class T>
    struct is_error_code_enum : public false_type {};

  template <class T>
    struct is_error_condition_enum : public false_type {};

  enum class errc {
    address_family_not_supported,       // EAFNOSUPPORT
    address_in_use,                     // EADDRINUSE
    address_not_available,              // EADDRNOTAVAIL
    already_connected,                  // EISCONN
    argument_list_too_long,             // E2BIG
    argument_out_of_domain,             // EDOM
    bad_address,                        // EFAULT
    bad_file_descriptor,                // EBADF
    bad_message,                        // EBADMSG
    broken_pipe,                        // EPIPE
    connection_aborted,                 // ECONNABORTED
    connection_already_in_progress,     // EALREADY
    connection_refused,                 // ECONNREFUSED
    connection_reset,                   // ECONNRESET
    cross_device_link,                  // EXDEV
    destination_address_required,       // EDESTADDRREQ
    device_or_resource_busy,            // EBUSY
    directory_not_empty,                // ENOTEMPTY
    executable_format_error,            // ENOEXEC
    file_exists,                        // EEXIST
    file_too_large,                     // EFBIG
    filename_too_long,                  // ENAMETOOLONG
    function_not_supported,             // ENOSYS
    host_unreachable,                   // EHOSTUNREACH
    identifier_removed,                 // EIDRM
    illegal_byte_sequence,              // EILSEQ
    inappropriate_io_control_operation, // ENOTTY
    interrupted,                        // EINTR
    invalid_argument,                   // EINVAL
    invalid_seek,                       // ESPIPE
    io_error,                           // EIO
    is_a_directory,                     // EISDIR
    message_size,                       // EMSGSIZE
    network_down,                       // ENETDOWN
    network_reset,                      // ENETRESET
    network_unreachable,                // ENETUNREACH
    no_buffer_space,                    // ENOBUFS
    no_child_process,                   // ECHILD
    no_link,                            // ENOLINK
    no_lock_available,                  // ENOLCK
    no_message_available,               // ENODATA
    no_message,                         // ENOMSG
    no_protocol_option,                 // ENOPROTOOPT
    no_space_on_device,                 // ENOSPC
    no_stream_resources,                // ENOSR
    no_such_device_or_address,          // ENXIO
    no_such_device,                     // ENODEV
    no_such_file_or_directory,          // ENOENT
    no_such_process,                    // ESRCH
    not_a_directory,                    // ENOTDIR
    not_a_socket,                       // ENOTSOCK
    not_a_stream,                       // ENOSTR
    not_connected,                      // ENOTCONN
    not_enough_memory,                  // ENOMEM
    not_supported,                      // ENOTSUP
    operation_canceled,                 // ECANCELED
    operation_in_progress,              // EINPROGRESS
    operation_not_permitted,            // EPERM
    operation_not_supported,            // EOPNOTSUPP
    operation_would_block,              // EWOULDBLOCK
    owner_dead,                         // EOWNERDEAD
    permission_denied,                  // EACCES
    protocol_error,                     // EPROTO
    protocol_not_supported,             // EPROTONOSUPPORT
    read_only_file_system,              // EROFS
    resource_deadlock_would_occur,      // EDEADLK
    resource_unavailable_try_again,     // EAGAIN
    result_out_of_range,                // ERANGE
    state_not_recoverable,              // ENOTRECOVERABLE
    stream_timeout,                     // ETIME
    text_file_busy,                     // ETXTBSY
    timed_out,                          // ETIMEDOUT
    too_many_files_open_in_system,      // ENFILE
    too_many_files_open,                // EMFILE
    too_many_links,                     // EMLINK
    too_many_symbolic_link_levels,      // ELOOP
    value_too_large,                    // EOVERFLOW
    wrong_protocol_type,                // EPROTOTYPE
  };

  template <> struct is_error_condition_enum<errc> : true_type {};

  // [syserr.errcode.nonmembers], non-member functions
  error_code make_error_code(errc e) noexcept;

  template <class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const error_code& ec);

  // [syserr.errcondition.nonmembers], non-member functions
  error_condition make_error_condition(errc e) noexcept;

  // [syserr.compare], comparison functions
  bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
  bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
  bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;

  // [syserr.hash], hash support
  template <class T> struct hash;
  template <> struct hash<error_code>;
  template <> struct hash<error_condition>;

  // [syserr], system error support
  template <class T>
    inline constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
  template <class T>
    inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value;
}
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.
The is_­error_­code_­enum and is_­error_­condition_­enum may be specialized for user-defined types to indicate that such types are eligible for class error_­code and class error_­condition automatic conversions, respectively.

22.5.2 Class error_­category [syserr.errcat]

22.5.2.1 Class error_­category overview [syserr.errcat.overview]

The class error_­category serves as a base class for types used to identify the source and encoding of a particular category of error code.
Classes may be derived from error_­category to support categories of errors in addition to those defined in this International Standard.
Such classes shall behave as specified in this subclause.
[Note
:
error_­category objects are passed by reference, and two such objects are equal if they have the same address.
This means that applications using custom error_­category types should create a single object of each such type.
end note
]
namespace std {
  class error_category {
  public:
    constexpr error_category() noexcept;
    virtual ~error_category();
    error_category(const error_category&) = delete;
    error_category& operator=(const error_category&) = delete;
    virtual const char* name() const noexcept = 0;
    virtual error_condition default_error_condition(int ev) const noexcept;
    virtual bool equivalent(int code, const error_condition& condition) const noexcept;
    virtual bool equivalent(const error_code& code, int condition) const noexcept;
    virtual string message(int ev) const = 0;

    bool operator==(const error_category& rhs) const noexcept;
    bool operator!=(const error_category& rhs) const noexcept;
    bool operator<(const error_category& rhs) const noexcept;
  };

  const error_category& generic_category() noexcept;
  const error_category& system_category() noexcept;
}

22.5.2.2 Class error_­category virtual members [syserr.errcat.virtuals]

virtual ~error_category();
Effects: Destroys an object of class error_­category.
virtual const char* name() const noexcept = 0;
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
Returns: error_­condition(ev, *this).
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
Returns: default_­error_­condition(code) == condition.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
Returns: *this == code.category() && code.value() == condition.
virtual string message(int ev) const = 0;
Returns: A string that describes the error condition denoted by ev.

22.5.2.3 Class error_­category non-virtual members [syserr.errcat.nonvirtuals]

constexpr error_category() noexcept;
Effects: Constructs an object of class error_­category.
bool operator==(const error_category& rhs) const noexcept;
Returns: this == &rhs.
bool operator!=(const error_category& rhs) const noexcept;
Returns: !(*this == rhs).
bool operator<(const error_category& rhs) const noexcept;
Returns: less<const error_­category*>()(this, &rhs).
[Note
:
less provides a total ordering for pointers.
end note
]

22.5.2.4 Program defined classes derived from error_­category [syserr.errcat.derived]

virtual const char* name() const noexcept = 0;
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
Returns: An object of type error_­condition that corresponds to ev.
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
Returns: true if, for the category of error represented by *this, code is considered equivalent to condition; otherwise, false.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
Returns: true if, for the category of error represented by *this, code is considered equivalent to condition; otherwise, false.

22.5.2.5 Error category objects [syserr.errcat.objects]

const error_category& generic_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
All calls to this function shall return references to the same object.
Remarks: The object's default_­error_­condition and equivalent virtual functions shall behave as specified for the class error_­category.
The object's name virtual function shall return a pointer to the string "generic".
const error_category& system_category() noexcept;
Returns: A reference to an object of a type derived from class error_­category.
All calls to this function shall return references to the same object.
Remarks: The object's equivalent virtual functions shall behave as specified for class error_­category.
The object's name virtual function shall return a pointer to the string "system".
The object's default_­error_­condition virtual function shall behave as follows:
If the argument ev corresponds to a POSIX errno value posv, the function shall return error_­condition(posv, generic_­category()).
Otherwise, the function shall return error_­condition(ev, system_­category()).
What constitutes correspondence for any given operating system is unspecified.
[Note
:
The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value.
Thus implementations are given latitude in determining correspondence.
end note
]

22.5.3 Class error_­code [syserr.errcode]

22.5.3.1 Class error_­code overview [syserr.errcode.overview]

The class error_­code describes an object used to hold error code values, such as those originating from the operating system or other low-level application program interfaces.
[Note
:
Class error_­code is an adjunct to error reporting by exception.
end note
]
namespace std {
  class error_code {
  public:
    // [syserr.errcode.constructors], constructors
    error_code() noexcept;
    error_code(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
      error_code(ErrorCodeEnum e) noexcept;

    // [syserr.errcode.modifiers], modifiers
    void assign(int val, const error_category& cat) noexcept;
    template <class ErrorCodeEnum>
      error_code& operator=(ErrorCodeEnum e) noexcept;
    void clear() noexcept;

    // [syserr.errcode.observers], observers
    int value() const noexcept;
    const error_category& category() const noexcept;
    error_condition default_error_condition() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // exposition only
    const error_category* cat_; // exposition only
  };

  // [syserr.errcode.nonmembers], non-member functions
  error_code make_error_code(errc e) noexcept;

  template <class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
}

22.5.3.2 Class error_­code constructors [syserr.errcode.constructors]

error_code() noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: val_­ == 0 and cat_­ == &system_­category().
error_code(int val, const error_category& cat) noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorCodeEnum> error_code(ErrorCodeEnum e) noexcept;
Effects: Constructs an object of type error_­code.
Postconditions: *this == make_­error_­code(e).
Remarks: This constructor shall not participate in overload resolution unless
is_­error_­code_­enum_­v<ErrorCodeEnum> is true.

22.5.3.3 Class error_­code modifiers [syserr.errcode.modifiers]

void assign(int val, const error_category& cat) noexcept;
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorCodeEnum> error_code& operator=(ErrorCodeEnum e) noexcept;
Postconditions: *this == make_­error_­code(e).
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless
is_­error_­code_­enum_­v<ErrorCodeEnum> is true.
void clear() noexcept;
Postconditions: value() == 0 and category() == system_­category().

22.5.3.4 Class error_­code observers [syserr.errcode.observers]

int value() const noexcept;
Returns: val_­.
const error_category& category() const noexcept;
Returns: *cat_­.
error_condition default_error_condition() const noexcept;
Returns: category().default_­error_­condition(value()).
string message() const;
Returns: category().message(value()).
explicit operator bool() const noexcept;
Returns: value() != 0.

22.5.3.5 Class error_­code non-member functions [syserr.errcode.nonmembers]

error_code make_error_code(errc e) noexcept;
Returns: error_­code(static_­cast<int>(e), generic_­category()).
template <class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
Effects: As if by: os << ec.category().name() << ':' << ec.value();

22.5.4 Class error_­condition [syserr.errcondition]

22.5.4.1 Class error_­condition overview [syserr.errcondition.overview]

The class error_­condition describes an object used to hold values identifying error conditions.
[Note
:
error_­condition values are portable abstractions, while error_­code values are implementation specific.
end note
]
namespace std {
  class error_condition {
  public:
    // [syserr.errcondition.constructors], constructors
    error_condition() noexcept;
    error_condition(int val, const error_category& cat) noexcept;
    template <class ErrorConditionEnum>
      error_condition(ErrorConditionEnum e) noexcept;

    // [syserr.errcondition.modifiers], modifiers
    void assign(int val, const error_category& cat) noexcept;
    template <class ErrorConditionEnum>
      error_condition& operator=(ErrorConditionEnum e) noexcept;
    void clear() noexcept;

    // [syserr.errcondition.observers], observers
    int value() const noexcept;
    const error_category& category() const noexcept;
    string message() const;
    explicit operator bool() const noexcept;

  private:
    int val_;                   // exposition only
    const error_category* cat_; // exposition only
  };
}

22.5.4.2 Class error_­condition constructors [syserr.errcondition.constructors]

error_condition() noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: val_­ == 0 and cat_­ == &generic_­category().
error_condition(int val, const error_category& cat) noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorConditionEnum> error_condition(ErrorConditionEnum e) noexcept;
Effects: Constructs an object of type error_­condition.
Postconditions: *this == make_­error_­condition(e).
Remarks: This constructor shall not participate in overload resolution unless
is_­error_­condition_­enum_­v<ErrorConditionEnum> is true.

22.5.4.3 Class error_­condition modifiers [syserr.errcondition.modifiers]

void assign(int val, const error_category& cat) noexcept;
Postconditions: val_­ == val and cat_­ == &cat.
template <class ErrorConditionEnum> error_condition& operator=(ErrorConditionEnum e) noexcept;
Postconditions: *this == make_­error_­condition(e).
Returns: *this.
Remarks: This operator shall not participate in overload resolution unless
is_­error_­condition_­enum_­v<ErrorConditionEnum> is true.
void clear() noexcept;
Postconditions: value() == 0 and category() == generic_­category().

22.5.4.4 Class error_­condition observers [syserr.errcondition.observers]

int value() const noexcept;
Returns: val_­.
const error_category& category() const noexcept;
Returns: *cat_­.
string message() const;
Returns: category().message(value()).
explicit operator bool() const noexcept;
Returns: value() != 0.

22.5.4.5 Class error_­condition non-member functions [syserr.errcondition.nonmembers]

error_condition make_error_condition(errc e) noexcept;
Returns: error_­condition(static_­cast<int>(e), generic_­category()).

22.5.5 Comparison functions [syserr.compare]

bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
Returns:
lhs.category() < rhs.category() ||
(lhs.category() == rhs.category() && lhs.value() < rhs.value());
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category() < rhs.category() || lhs.category() == rhs.category() &&
lhs.value() < rhs.value()
.
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value().
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs, rhs.value()).
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
Returns: rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs, lhs.value()).
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value().
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: !(lhs == rhs).

22.5.6 System error hash support [syserr.hash]

template <> struct hash<error_code>; template <> struct hash<error_condition>;
The specializations are enabled ([unord.hash]).

22.5.7 Class system_­error [syserr.syserr]

22.5.7.1 Class system_­error overview [syserr.syserr.overview]

The class system_­error describes an exception object used to report error conditions that have an associated error code.
Such error conditions typically originate from the operating system or other low-level application program interfaces.
[Note
:
If an error represents an out-of-memory condition, implementations are encouraged to throw an exception object of type bad_­alloc rather than system_­error.
end note
]
namespace std {
  class system_error : public runtime_error {
  public:
    system_error(error_code ec, const string& what_arg);
    system_error(error_code ec, const char* what_arg);
    system_error(error_code ec);
    system_error(int ev, const error_category& ecat, const string& what_arg);
    system_error(int ev, const error_category& ecat, const char* what_arg);
    system_error(int ev, const error_category& ecat);
    const error_code& code() const noexcept;
    const char* what() const noexcept override;
  };
}

22.5.7.2 Class system_­error members [syserr.syserr.members]

system_error(error_code ec, const string& what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
string(what()).find(what_­arg) != string​::​npos.
system_error(error_code ec, const char* what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
string(what()).find(what_­arg) != string​::​npos.
system_error(error_code ec);
Effects: Constructs an object of class system_­error.
Postconditions: code() == ec.
system_error(int ev, const error_category& ecat, const string& what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
string(what()).find(what_­arg) != string​::​npos.
system_error(int ev, const error_category& ecat, const char* what_arg);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
string(what()).find(what_­arg) != string​::​npos.
system_error(int ev, const error_category& ecat);
Effects: Constructs an object of class system_­error.
Postconditions: code() == error_­code(ev, ecat).
const error_code& code() const noexcept;
Returns: ec or error_­code(ev, ecat), from the constructor, as appropriate.
const char* what() const noexcept override;
Returns: An ntbs incorporating the arguments supplied in the constructor.
[Note
:
The returned ntbs might be the contents of what_­arg + ": " + code.message().
end note
]