19 Diagnostics library [diagnostics]

19.1 General [diagnostics.general]

This Clause describes components that C++ programs may use to detect and report error conditions.
The following subclauses describe components for reporting several kinds of exceptional conditions, documenting program assertions, obtaining stacktraces, and a global variable for error number codes, as summarized in Table 46.
Table 46: Diagnostics library summary [tab:diagnostics.summary]
Subclause
Header
Exception classes
<stdexcept>
Assertions
<cassert>
Error numbers
<cerrno>
System error support
<system_error>
Stacktrace
<stacktrace>
Debugging
<debugging>

19.2 Exception classes [std.exceptions]

19.2.1 General [std.exceptions.general]

The C++ standard library provides classes to be used to report certain errors ([res.on.exception.handling]) in C++ programs.
In the error model reflected in these classes, errors are divided into two broad categories: logic errors and runtime errors.
The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the program.
In theory, they are preventable.
By contrast, runtime errors are due to events beyond the scope of the program.
They cannot be easily predicted in advance.
The header <stdexcept> defines several types of predefined exceptions for reporting errors in a C++ program.
These exceptions are related by inheritance.

19.2.2 Header <stdexcept> synopsis [stdexcept.syn]

namespace std { class logic_error; class domain_error; class invalid_argument; class length_error; class out_of_range; class runtime_error; class range_error; class overflow_error; class underflow_error; }

19.2.3 Class logic_error [logic.error]

namespace std { class logic_error : public exception { public: explicit logic_error(const string& what_arg); explicit logic_error(const char* what_arg); }; }
The class logic_error defines the type of objects thrown as exceptions to report errors presumably detectable before the program executes, such as violations of logical preconditions or class invariants.
logic_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
logic_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.4 Class domain_error [domain.error]

namespace std { class domain_error : public logic_error { public: explicit domain_error(const string& what_arg); explicit domain_error(const char* what_arg); }; }
The class domain_error defines the type of objects thrown as exceptions by the implementation to report domain errors.
domain_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
domain_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.5 Class invalid_argument [invalid.argument]

namespace std { class invalid_argument : public logic_error { public: explicit invalid_argument(const string& what_arg); explicit invalid_argument(const char* what_arg); }; }
The class invalid_argument defines the type of objects thrown as exceptions to report an invalid argument.
invalid_argument(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
invalid_argument(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.6 Class length_error [length.error]

namespace std { class length_error : public logic_error { public: explicit length_error(const string& what_arg); explicit length_error(const char* what_arg); }; }
The class length_error defines the type of objects thrown as exceptions to report an attempt to produce an object whose length exceeds its maximum allowable size.
length_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
length_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.7 Class out_of_range [out.of.range]

namespace std { class out_of_range : public logic_error { public: explicit out_of_range(const string& what_arg); explicit out_of_range(const char* what_arg); }; }
The class out_of_range defines the type of objects thrown as exceptions to report an argument value not in its expected range.
out_of_range(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
out_of_range(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.8 Class runtime_error [runtime.error]

namespace std { class runtime_error : public exception { public: explicit runtime_error(const string& what_arg); explicit runtime_error(const char* what_arg); }; }
The class runtime_error defines the type of objects thrown as exceptions to report errors presumably detectable only when the program executes.
runtime_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
runtime_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.9 Class range_error [range.error]

namespace std { class range_error : public runtime_error { public: explicit range_error(const string& what_arg); explicit range_error(const char* what_arg); }; }
The class range_error defines the type of objects thrown as exceptions to report range errors in internal computations.
range_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
range_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.10 Class overflow_error [overflow.error]

namespace std { class overflow_error : public runtime_error { public: explicit overflow_error(const string& what_arg); explicit overflow_error(const char* what_arg); }; }
The class overflow_error defines the type of objects thrown as exceptions to report an arithmetic overflow error.
overflow_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
overflow_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.2.11 Class underflow_error [underflow.error]

namespace std { class underflow_error : public runtime_error { public: explicit underflow_error(const string& what_arg); explicit underflow_error(const char* what_arg); }; }
The class underflow_error defines the type of objects thrown as exceptions to report an arithmetic underflow error.
underflow_error(const string& what_arg);
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
underflow_error(const char* what_arg);
Postconditions: strcmp(what(), what_arg) == 0.

19.3 Assertions [assertions]

19.3.1 General [assertions.general]

The header <cassert> provides a macro for documenting C++ program assertions and a mechanism for disabling the assertion checks through defining the macro NDEBUG.

19.3.2 Header <cassert> synopsis [cassert.syn]

#define assert(...) see below

19.3.3 The assert macro [assertions.assert]

If NDEBUG is defined as a macro name at the point in the source file where <cassert> is included, the assert macro is defined as #define assert(...) ((void)0)
Otherwise, the assert macro puts a diagnostic test into programs; it expands to an expression of type void which has the following effects:
  • __VA_ARGS__ is evaluated and contextually converted to bool.
  • If the evaluation yields true there are no further effects.
  • Otherwise, the assert macro's expression creates a diagnostic on the standard error stream in an implementation-defined format and calls abort().
    The diagnostic contains #__VA_ARGS__ and information on the name of the source file, the source line number, and the name of the enclosing function (such as provided by source_location​::​current()).
If __VA_ARGS__ does not expand to an assignment-expression, the program is ill-formed.
The macro assert is redefined according to the current state of NDEBUG each time that <cassert> is included.
An expression assert(E) is a constant subexpression, if

19.4 Error numbers [errno]

19.4.1 General [errno.general]

The contents of the header <cerrno> are the same as the POSIX header <errno.h>, except that errno shall be defined as a macro.
[Note 1: 
The intent is to remain in close alignment with the POSIX standard.
— end note]
A separate errno value is provided for each thread.

19.4.2 Header <cerrno> synopsis [cerrno.syn]

#define errno see below #define E2BIG see below // freestanding #define EACCES see below // freestanding #define EADDRINUSE see below // freestanding #define EADDRNOTAVAIL see below // freestanding #define EAFNOSUPPORT see below // freestanding #define EAGAIN see below // freestanding #define EALREADY see below // freestanding #define EBADF see below // freestanding #define EBADMSG see below // freestanding #define EBUSY see below // freestanding #define ECANCELED see below // freestanding #define ECHILD see below // freestanding #define ECONNABORTED see below // freestanding #define ECONNREFUSED see below // freestanding #define ECONNRESET see below // freestanding #define EDEADLK see below // freestanding #define EDESTADDRREQ see below // freestanding #define EDOM see below // freestanding #define EEXIST see below // freestanding #define EFAULT see below // freestanding #define EFBIG see below // freestanding #define EHOSTUNREACH see below // freestanding #define EIDRM see below // freestanding #define EILSEQ see below // freestanding #define EINPROGRESS see below // freestanding #define EINTR see below // freestanding #define EINVAL see below // freestanding #define EIO see below // freestanding #define EISCONN see below // freestanding #define EISDIR see below // freestanding #define ELOOP see below // freestanding #define EMFILE see below // freestanding #define EMLINK see below // freestanding #define EMSGSIZE see below // freestanding #define ENAMETOOLONG see below // freestanding #define ENETDOWN see below // freestanding #define ENETRESET see below // freestanding #define ENETUNREACH see below // freestanding #define ENFILE see below // freestanding #define ENOBUFS see below // freestanding #define ENODEV see below // freestanding #define ENOENT see below // freestanding #define ENOEXEC see below // freestanding #define ENOLCK see below // freestanding #define ENOLINK see below // freestanding #define ENOMEM see below // freestanding #define ENOMSG see below // freestanding #define ENOPROTOOPT see below // freestanding #define ENOSPC see below // freestanding #define ENOSYS see below // freestanding #define ENOTCONN see below // freestanding #define ENOTDIR see below // freestanding #define ENOTEMPTY see below // freestanding #define ENOTRECOVERABLE see below // freestanding #define ENOTSOCK see below // freestanding #define ENOTSUP see below // freestanding #define ENOTTY see below // freestanding #define ENXIO see below // freestanding #define EOPNOTSUPP see below // freestanding #define EOVERFLOW see below // freestanding #define EOWNERDEAD see below // freestanding #define EPERM see below // freestanding #define EPIPE see below // freestanding #define EPROTO see below // freestanding #define EPROTONOSUPPORT see below // freestanding #define EPROTOTYPE see below // freestanding #define ERANGE see below // freestanding #define EROFS see below // freestanding #define ESPIPE see below // freestanding #define ESRCH see below // freestanding #define ETIMEDOUT see below // freestanding #define ETXTBSY see below // freestanding #define EWOULDBLOCK see below // freestanding #define EXDEV see below // freestanding
The meaning of the macros in this header is defined by the POSIX standard.
See also: ISO/IEC 9899:2018, 7.5

19.5 System error support [syserr]

19.5.1 General [syserr.general]

Subclause [syserr] 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 [syserr] do not change the value of errno ([errno]).
Recommended practice: Implementations should leave the error states provided by other libraries unchanged.

19.5.2 Header <system_error> synopsis [system.error.syn]

#include <compare> // see [compare.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 { // freestanding 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, // ENOMSG no_protocol_option, // ENOPROTOOPT no_space_on_device, // ENOSPC 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_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 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 operator functions 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_condition& rhs) noexcept; strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept; strong_ordering 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> constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value; template<class T> constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value; }
The value of each enum errc enumerator is 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 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.

19.5.3 Class error_category [syserr.errcat]

19.5.3.1 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 document.
Such classes shall behave as specified in subclause [syserr.errcat].
[Note 1: 
error_category objects are passed by reference, and two such objects are equal if they have the same address.
If there is more than a single object of a custom error_category type, such equality comparisons can evaluate to false even for objects holding the same value.
— 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; strong_ordering operator<=>(const error_category& rhs) const noexcept; }; const error_category& generic_category() noexcept; const error_category& system_category() noexcept; }

19.5.3.2 Virtual members [syserr.errcat.virtuals]

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.

19.5.3.3 Non-virtual members [syserr.errcat.nonvirtuals]

bool operator==(const error_category& rhs) const noexcept;
Returns: this == &rhs.
strong_ordering operator<=>(const error_category& rhs) const noexcept;
Returns: compare_three_way()(this, &rhs).
[Note 1: 
compare_three_way ([comparisons.three.way]) provides a total ordering for pointers.
— end note]

19.5.3.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.

19.5.3.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 is equal to 0, the function returns error_condition(0, generic_category()).
Otherwise, if ev corresponds to a POSIX errno value pxv, the function returns error_condition(pxv, generic_category()).
Otherwise, the function returns error_condition(ev, system_category()).
What constitutes correspondence for any given operating system is unspecified.
[Note 1: 
The number of potential system error codes is large and unbounded, and some might not correspond to any POSIX errno value.
Thus implementations are given latitude in determining correspondence.
— end note]

19.5.4 Class error_code [syserr.errcode]

19.5.4.1 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 1: 
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); }

19.5.4.2 Constructors [syserr.errcode.constructors]

error_code() noexcept;
Effects: Initializes val_ with 0 and cat_ with &system_category().
error_code(int val, const error_category& cat) noexcept;
Effects: Initializes val_ with val and cat_ with &cat.
template<class ErrorCodeEnum> error_code(ErrorCodeEnum e) noexcept;
Constraints: is_error_code_enum_v<ErrorCodeEnum> is true.
Effects: Equivalent to: error_code ec = make_error_code(e); assign(ec.value(), ec.category());

19.5.4.3 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;
Constraints: is_error_code_enum_v<ErrorCodeEnum> is true.
Effects: Equivalent to: error_code ec = make_error_code(e); assign(ec.value(), ec.category());
Returns: *this.
void clear() noexcept;
Postconditions: value() == 0 and category() == system_category().

19.5.4.4 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.

19.5.4.5 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: Equivalent to: return os << ec.category().name() << ':' << ec.value();

19.5.5 Class error_condition [syserr.errcondition]

19.5.5.1 Overview [syserr.errcondition.overview]

The class error_condition describes an object used to hold values identifying error conditions.
[Note 1: 
error_condition values are portable abstractions, while error_code values ([syserr.errcode]) 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 }; }

19.5.5.2 Constructors [syserr.errcondition.constructors]

error_condition() noexcept;
Effects: Initializes val_ with 0 and cat_ with &generic_category().
error_condition(int val, const error_category& cat) noexcept;
Effects: Initializes val_ with val and cat_ with &cat.
template<class ErrorConditionEnum> error_condition(ErrorConditionEnum e) noexcept;
Constraints: is_error_condition_enum_v<ErrorConditionEnum> is true.
Effects: Equivalent to: error_condition ec = make_error_condition(e); assign(ec.value(), ec.category());

19.5.5.3 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;
Constraints: is_error_condition_enum_v<ErrorConditionEnum> is true.
Effects: Equivalent to: error_condition ec = make_error_condition(e); assign(ec.value(), ec.category());
Returns: *this.
void clear() noexcept;
Postconditions: value() == 0 and category() == generic_category().

19.5.5.4 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.

19.5.5.5 Non-member functions [syserr.errcondition.nonmembers]

error_condition make_error_condition(errc e) noexcept;
Returns: error_condition(static_cast<int>(e), generic_category()).

19.5.6 Comparison operator functions [syserr.compare]

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_condition& rhs) noexcept;
Returns: lhs.category() == rhs.category() && lhs.value() == rhs.value()
strong_ordering operator<=>(const error_code& lhs, const error_code& rhs) noexcept;
Effects: Equivalent to: if (auto c = lhs.category() <=> rhs.category(); c != 0) return c; return lhs.value() <=> rhs.value();
strong_ordering operator<=>(const error_condition& lhs, const error_condition& rhs) noexcept;
Returns: if (auto c = lhs.category() <=> rhs.category(); c != 0) return c; return lhs.value() <=> rhs.value();

19.5.7 System error hash support [syserr.hash]

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

19.5.8 Class system_error [syserr.syserr]

19.5.8.1 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 1: 
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; }; }

19.5.8.2 Members [syserr.syserr.members]

system_error(error_code ec, const string& what_arg);
Postconditions: code() == ec and
string_view(what()).find(what_arg.c_str()) != string_view​::​npos.
system_error(error_code ec, const char* what_arg);
Postconditions: code() == ec and string_view(what()).find(what_arg) != string_view​::​npos.
system_error(error_code ec);
Postconditions: code() == ec.
system_error(int ev, const error_category& ecat, const string& what_arg);
Postconditions: code() == error_code(ev, ecat) and
string_view(what()).find(what_arg.c_str()) != string_view​::​npos.
system_error(int ev, const error_category& ecat, const char* what_arg);
Postconditions: code() == error_code(ev, ecat) and
string_view(what()).find(what_arg) != string_view​::​npos.
system_error(int ev, const error_category& ecat);
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 1: 
The returned ntbs might be the contents of what_arg + ": " + code.message().
— end note]

19.6 Stacktrace [stacktrace]

19.6.1 General [stacktrace.general]

Subclause [stacktrace] describes components that C++ programs may use to store the stacktrace of the current thread of execution and query information about the stored stacktrace at runtime.
The invocation sequence of the current evaluation in the current thread of execution is a sequence of evaluations such that, for i  ≥ 0, is within the function invocation ([intro.execution]).
A stacktrace is an approximate representation of an invocation sequence and consists of stacktrace entries.
A stacktrace entry represents an evaluation in a stacktrace.

19.6.2 Header <stacktrace> synopsis [stacktrace.syn]

#include <compare> // see [compare.syn] namespace std { // [stacktrace.entry], class stacktrace_entry class stacktrace_entry; // [stacktrace.basic], class template basic_stacktrace template<class Allocator> class basic_stacktrace; // basic_stacktrace typedef-names using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>; // [stacktrace.basic.nonmem], non-member functions template<class Allocator> void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b) noexcept(noexcept(a.swap(b))); string to_string(const stacktrace_entry& f); template<class Allocator> string to_string(const basic_stacktrace<Allocator>& st); ostream& operator<<(ostream& os, const stacktrace_entry& f); template<class Allocator> ostream& operator<<(ostream& os, const basic_stacktrace<Allocator>& st); // [stacktrace.format], formatting support template<> struct formatter<stacktrace_entry>; template<class Allocator> struct formatter<basic_stacktrace<Allocator>>; namespace pmr { using stacktrace = basic_stacktrace<polymorphic_allocator<stacktrace_entry>>; } // [stacktrace.basic.hash], hash support template<class T> struct hash; template<> struct hash<stacktrace_entry>; template<class Allocator> struct hash<basic_stacktrace<Allocator>>; }

19.6.3 Class stacktrace_entry [stacktrace.entry]

19.6.3.1 Overview [stacktrace.entry.overview]

namespace std { class stacktrace_entry { public: using native_handle_type = implementation-defined; // [stacktrace.entry.cons], constructors constexpr stacktrace_entry() noexcept; constexpr stacktrace_entry(const stacktrace_entry& other) noexcept; constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept; ~stacktrace_entry(); // [stacktrace.entry.obs], observers constexpr native_handle_type native_handle() const noexcept; constexpr explicit operator bool() const noexcept; // [stacktrace.entry.query], query string description() const; string source_file() const; uint_least32_t source_line() const; // [stacktrace.entry.cmp], comparison friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; friend constexpr strong_ordering operator<=>(const stacktrace_entry& x, const stacktrace_entry& y) noexcept; }; }
An object of type stacktrace_entry is either empty, or represents a stacktrace entry and provides operations for querying information about it.
The class stacktrace_entry models regular ([concepts.object]) and three_way_comparable<strong_ordering> ([cmp.concept]).

19.6.3.2 Constructors [stacktrace.entry.cons]

constexpr stacktrace_entry() noexcept;
Postconditions: *this is empty.

19.6.3.3 Observers [stacktrace.entry.obs]

constexpr native_handle_type native_handle() const noexcept;
The semantics of this function are implementation-defined.
Remarks: Successive invocations of the native_handle function for an unchanged stacktrace_entry object return identical values.
constexpr explicit operator bool() const noexcept;
Returns: false if and only if *this is empty.

19.6.3.4 Query [stacktrace.entry.query]

[Note 1: 
All the stacktrace_entry query functions treat errors other than memory allocation errors as “no information available” and do not throw in that case.
— end note]
string description() const;
Returns: A description of the evaluation represented by *this, or an empty string.
Throws: bad_alloc if memory for the internal data structures or the resulting string cannot be allocated.
string source_file() const;
Returns: The presumed or actual name of the source file ([cpp.predefined]) that lexically contains the expression or statement whose evaluation is represented by *this, or an empty string.
Throws: bad_alloc if memory for the internal data structures or the resulting string cannot be allocated.
uint_least32_t source_line() const;
Returns: 0, or a 1-based line number that lexically relates to the evaluation represented by *this.
If source_file returns the presumed name of the source file, returns the presumed line number; if source_file returns the actual name of the source file, returns the actual line number.
Throws: bad_alloc if memory for the internal data structures cannot be allocated.

19.6.3.5 Comparison [stacktrace.entry.cmp]

friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
Returns: true if and only if x and y represent the same stacktrace entry or both x and y are empty.

19.6.4 Class template basic_stacktrace [stacktrace.basic]

19.6.4.1 Overview [stacktrace.basic.overview]

namespace std { template<class Allocator> class basic_stacktrace { public: using value_type = stacktrace_entry; using const_reference = const value_type&; using reference = value_type&; using const_iterator = implementation-defined; // see [stacktrace.basic.obs] using iterator = const_iterator; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using difference_type = implementation-defined; using size_type = implementation-defined; using allocator_type = Allocator; // [stacktrace.basic.cons], creation and assignment static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept; static basic_stacktrace current(size_type skip, size_type max_depth, const allocator_type& alloc = allocator_type()) noexcept; basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>); explicit basic_stacktrace(const allocator_type& alloc) noexcept; basic_stacktrace(const basic_stacktrace& other); basic_stacktrace(basic_stacktrace&& other) noexcept; basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); basic_stacktrace& operator=(const basic_stacktrace& other); basic_stacktrace& operator=(basic_stacktrace&& other) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value); ~basic_stacktrace(); // [stacktrace.basic.obs], observers allocator_type get_allocator() const noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; const_reference operator[](size_type) const; const_reference at(size_type) const; // [stacktrace.basic.cmp], comparisons template<class Allocator2> friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; template<class Allocator2> friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept; // [stacktrace.basic.mod], modifiers void swap(basic_stacktrace& other) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value); private: vector<value_type, allocator_type> frames_; // exposition only }; }
The class template basic_stacktrace satisfies the requirements of a reversible container ([container.rev.reqmts]), of an allocator-aware container ([container.alloc.reqmts]), and of a sequence container ([sequence.reqmts]), except that
  • only move, assignment, swap, and operations defined for const-qualified sequence containers are supported and,
  • the semantics of comparison functions are different from those required for a container.

19.6.4.2 Creation and assignment [stacktrace.basic.cons]

static basic_stacktrace current(const allocator_type& alloc = allocator_type()) noexcept;
Returns: A basic_stacktrace object with frames_ storing the stacktrace of the current evaluation in the current thread of execution, or an empty basic_stacktrace object if the initialization of frames_ failed.
alloc is passed to the constructor of the frames_ object.
[Note 1: 
If the stacktrace was successfully obtained, then frames_.front() is the stacktrace_entry representing approximately the current evaluation, and frames_.back() is the stacktrace_entry representing approximately the initial function of the current thread of execution.
— end note]
static basic_stacktrace current(size_type skip, const allocator_type& alloc = allocator_type()) noexcept;
Let t be a stacktrace as-if obtained via basic_stacktrace​::​current(alloc).
Let n be t.size().
Returns: A basic_stacktrace object where frames_ is direct-non-list-initialized from arguments t.begin() + min(n, skip), t.end(), and alloc, or an empty basic_stacktrace object if the initialization of frames_ failed.
static basic_stacktrace current(size_type skip, size_type max_depth, const allocator_type& alloc = allocator_type()) noexcept;
Let t be a stacktrace as-if obtained via basic_stacktrace​::​current(alloc).
Let n be t.size().
Preconditions: skip <= skip + max_depth is true.
Returns: A basic_stacktrace object where frames_ is direct-non-list-initialized from arguments t.begin() + min(n, skip), t.begin() + min(n, skip + max_depth), and alloc, or an empty basic_stacktrace object if the initialization of frames_ failed.
basic_stacktrace() noexcept(is_nothrow_default_constructible_v<allocator_type>);
Postconditions: empty() is true.
explicit basic_stacktrace(const allocator_type& alloc) noexcept;
Effects: alloc is passed to the frames_ constructor.
Postconditions: empty() is true.
basic_stacktrace(const basic_stacktrace& other); basic_stacktrace(const basic_stacktrace& other, const allocator_type& alloc); basic_stacktrace(basic_stacktrace&& other, const allocator_type& alloc); basic_stacktrace& operator=(const basic_stacktrace& other); basic_stacktrace& operator=(basic_stacktrace&& other) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Remarks: Implementations may strengthen the exception specification for these functions ([res.on.exception.handling]) by ensuring that empty() is true on failed allocation.

19.6.4.3 Observers [stacktrace.basic.obs]

using const_iterator = implementation-defined;
The type models random_access_iterator ([iterator.concept.random.access]) and meets the Cpp17RandomAccessIterator requirements ([random.access.iterators]).
allocator_type get_allocator() const noexcept;
Returns: frames_.get_allocator().
const_iterator begin() const noexcept; const_iterator cbegin() const noexcept;
Returns: An iterator referring to the first element in frames_.
If empty() is true, then it returns the same value as end().
const_iterator end() const noexcept; const_iterator cend() const noexcept;
Returns: The end iterator.
const_reverse_iterator rbegin() const noexcept; const_reverse_iterator crbegin() const noexcept;
Returns: reverse_iterator(cend()).
const_reverse_iterator rend() const noexcept; const_reverse_iterator crend() const noexcept;
Returns: reverse_iterator(cbegin()).
bool empty() const noexcept;
Returns: frames_.empty().
size_type size() const noexcept;
Returns: frames_.size().
size_type max_size() const noexcept;
Returns: frames_.max_size().
const_reference operator[](size_type frame_no) const;
Preconditions: frame_no < size() is true.
Returns: frames_[frame_no].
Throws: Nothing.
const_reference at(size_type frame_no) const;
Returns: frames_[frame_no].
Throws: out_of_range if frame_no >= size().

19.6.4.4 Comparisons [stacktrace.basic.cmp]

template<class Allocator2> friend bool operator==(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
Returns: equal(x.begin(), x.end(), y.begin(), y.end()).
template<class Allocator2> friend strong_ordering operator<=>(const basic_stacktrace& x, const basic_stacktrace<Allocator2>& y) noexcept;
Returns: x.size() <=> y.size() if x.size() != y.size(); lexicographical_compare_three_way(x.begin(), x.end(), y.begin(), y.end()) otherwise.

19.6.4.5 Modifiers [stacktrace.basic.mod]

void swap(basic_stacktrace& other) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Exchanges the contents of *this and other.

19.6.4.6 Non-member functions [stacktrace.basic.nonmem]

template<class Allocator> void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b) noexcept(noexcept(a.swap(b)));
Effects: Equivalent to a.swap(b).
string to_string(const stacktrace_entry& f);
Returns: A string with a description of f.
Recommended practice: The description should provide information about the contained evaluation, including information from f.source_file() and f.source_line().
template<class Allocator> string to_string(const basic_stacktrace<Allocator>& st);
Returns: A string with a description of st.
[Note 1: 
The number of lines is not guaranteed to be equal to st.size().
— end note]
ostream& operator<<(ostream& os, const stacktrace_entry& f);
Effects: Equivalent to: return os << to_string(f);
template<class Allocator> ostream& operator<<(ostream& os, const basic_stacktrace<Allocator>& st);
Effects: Equivalent to: return os << to_string(st);

19.6.5 Formatting support [stacktrace.format]

template<> struct formatter<stacktrace_entry>;
formatter<stacktrace_entry> interprets format-spec as a stacktrace-entry-format-spec.
The syntax of format specifications is as follows:
stacktrace-entry-format-spec:
fill-and-align width
[Note 1: 
The productions fill-and-align and width are described in [format.string.std].
— end note]
A stacktrace_entry object se is formatted as if by copying to_string(se) through the output iterator of the context with additional padding and adjustments as specified by the format specifiers.
template<class Allocator> struct formatter<basic_stacktrace<Allocator>>;
For formatter<basic_stacktrace<Allocator>>, format-spec is empty.
A basic_stacktrace<Allocator> object s is formatted as if by copying to_string(s) through the output iterator of the context.

19.6.6 Hash support [stacktrace.basic.hash]

template<> struct hash<stacktrace_entry>; template<class Allocator> struct hash<basic_stacktrace<Allocator>>;
The specializations are enabled ([unord.hash]).

19.7 Debugging [debugging]

19.7.1 General [debugging.general]

Subclause [debugging] describes functionality to introspect and interact with the execution of the program.
[Note 1: 
The facilities provided by the debugging functionality interact with a program that could be tracing the execution of a C++ program, such as a debugger.
— end note]

19.7.2 Header <debugging> synopsis [debugging.syn]

// all freestanding namespace std { // [debugging.utility], utility void breakpoint() noexcept; void breakpoint_if_debugging() noexcept; bool is_debugger_present() noexcept; }

19.7.3 Utility [debugging.utility]

void breakpoint() noexcept;
The semantics of this function are implementation-defined.
[Note 1: 
When invoked, the execution of the program temporarily halts and execution is handed to the debugger until such a time as: The program is terminated by the debugger, or the debugger resumes execution of the program as if the function was not invoked.
— end note]
void breakpoint_if_debugging() noexcept;
Effects: Equivalent to: if (is_debugger_present()) breakpoint();
bool is_debugger_present() noexcept;
Replaceable: A C++ program may define a function with this function signature, and thereby displace the default version defined by the C++ standard library.
Required behavior: This function has no preconditions.
Default behavior: implementation-defined.
[Note 2: 
When tracing the execution of a program with a debugger, an implementation returns true.
An implementation performs an immediate query, as needed, to determine if the program is traced by a debugger.
On Windows or equivalent systems, this can be achieved by calling the ​::​IsDebuggerPresent() Win32 function.
On POSIX, this can be achieved by checking for a tracer parent process, with best effort determination that such a tracer parent process is a debugger.
— end note]