The C++ language and standard library provides several mechanisms for error handling:
std::string::npos
.std::expected<T,E>
or std::optional<T>
for a return type T
.errno
, or as an object’s status as with std::istream
’s flags. The standard library provides std::error_code
that can be used to map errno
values for further processing.Many parts of the standard library specify preconditions and undefined behavior [EWF] results if those aren’t met, for example, std::vector<int>::front()
requires a non-empty vector, when called.
Exceptions allow errors to be propagated up the call chain to a matching handler, or to program termination. Even though the standard library provides a type hierarchy derived from std::exception
, any copyable type can be thrown. Throwing an exception due to a detected error situation allows the error to be handled at an appropriate level in a corresponding catch block. As the exception propagates to its handler, local objects are destroyed appropriately in reverse order of their construction in a mechanism known as stack unwinding. A search for a matching handler stops at - the function main()
, - a function declared noexcept
, and - the function of a thread.
An exception propagated from constructors of non-local variables and destructors of variables with static storage duration can never have a matching handler.
Failing to provide a matching handler on the call chain for an exception thrown causes a call to std::terminate()
and the program terminates.
When calling non-returning program termination functions like abort()
, std::terminate()
, or exit()
, the program terminates without stack unwinding.
#TODO: shorten again by moving to 6.36? talk about coroutines… see what Paul finds out
An exception propagating out of a coroutine causes the coroutine to end in an unresumable state and the exception is not further propagated.
NOTE: The following may be moved to a clause 7 vulnerability or into 6.4. eg. float128_t
There is another form of floating point error handling. IEEE 754 calls them floating point exceptions but they are unrelated to C++ exceptions.
Used by any library functions external to C++, and by some C++ libraries.
errno is a thread-local single value that, if non-zero, reports an error that has occurred and is returned by function as the return value.
Any external can be called using error_code which will wrap the errno.
error_code is an extension or errno but is not a global variable and can work with classes for better reporting.
In addition to that list, an operating system might use the “signal” mechanism to notify a running C++ program. A signal-handler can be defined to act asynchronously upon a sent signal that isn’t ignored.