This paper outlines changes in the way std::exception
and
derived classes are designed and used in the draft C++0x library. It
attempts to survey existing C++ practice, and detail defects in the
C++03 standard that have risen to the surface after almost a decade of
use. As such, it falls into the categories of removing embarrassments,
increasing consistency, and making C++ easier to teach and learn.
In the last decade, all implementations of the C++ standard library have had to design modes such that the library is compilable without exception handling enabled, and all compilers of the C++ language have flags for turning off exception support. A quick look at other major C++ libraries such as Boost, ACE, and others show similar scars. It is not necessary to argue why this is so, if the performance differences between exception enabled and exception disabled code is measurable or significant, if this is a preference or a religion, a practice based in fact or fiction.
Instead, a new tack: confronting reality. Apparently, not every C++ user is willing to pay for all costs of the full language, and exceptions impose a cost unconditionally on many widely available toolchains.
Implementations for a library capable of being compiled both with
and without exception support and are divided into two major concerns:
what to do about the actual throw
expressions (and the
related exception
classes), and what to do with control
flow (the try
and catch
blocks).
For the first concern, all implementations seem to have similar approaches: the creation of an include file that has function declarations for throwing each of the exception classes defined in the standard, and for re-throwing exception classes. This is a possible candidate for standardization. (Another approach is elaborated below, whereby a level of indirection is inserted between raising an error and the actual throw expression, where the throw expression is optional if compiling without exception support.)
It is an open question if alternate error and diagnostic
frameworks such as found in <system_error>
could be
integrated into this solution such that the no-exceptions code paths
still have some kind of error checking.
The second concern has less uniform solutions: some
implementations transform try
and catch
blocks into #if 1
and #if 0
blocks when
compiling without exceptions at the pre-processor level, others
macro-ize all try
and catch
blocks, and do
pre-processing to convert to try
and catch
blocks when compiling with exceptions and something else when
compiling without exceptions. Standardizing this behavior seems like a
less likely candidate for library standardization, but perhaps a
language solution exists. If existing compiler support for compilation
of C++ without exceptions could be standardized, or even made optional
or a measure of QoI, this issue could be handily solved. It would be
better, however, if existing (minimal) support was modified such that
transformation of try
and catch
was done as
part of the (non pre-processor) compilation process, and not via a
library solution. The end goal of this modification would improve
legibility, by allowing unconditional use of existing C++
try
and catch
syntax, but transforming it to
some benign form in the absence of true exception support.
exception
classes and hierarchySeveral areas of improvement come to mind.
Consistent naming of exception classes, library wide. Pick
_error
suffix, or bad_
prefix, or invent
something new, but suggest a common naming scheme that all exception
classes follow. As part of this, the exception base class should have
_base
suffix.
Removal of warts and inconsistencies in current logic and
design. For instance, all exceptions force a stack unwind, which can
only occur at runtime, yet there is runtime_error
. Why?
The io exception (ios_base::failure
) is a nested class,
yet none of the other exceptions are. Why? The end goal would be to
design exception classes for the standard library that Bjarne wouldn't
savage in his books.
Remove duplication between <system_error>
components thrown by not_enough_memory
and the existing
bad_alloc
, or io_error
and the existing
ios_base::failure
, etc. This could take the form of
removing the system_error
exception class, or integrating
its functionality into exception
, or some other
solution.
Make sure that there is a one-to-one mapping between the diagnostic
codes in <system_error>
and exception classes in
<stdexcept>
. Giving all errors a one-to-one match
with exceptions will allow mapping between error/diagnostic constants
and exception classes. (And thus coherent error handling between
exception-enabled and exception-disabled source code.)
Change derivation to be virtual public
for exception
hierarchy. This would match other parts of the existing library design
for class hierarchies, such as ostream
and
istream
deriving virtual public
from
basic_ios
. There are at least two advantages of this
change:
1. Third derivations are now unambiguous. Example (modification of the issue detailed by David Abrahams).
#include <stdexcept> struct bad_non_virtual : virtual public std::exception { }; struct diamond_error : std::bad_exception, bad_non_virtual { }; int main() { try { throw diamond_error(); } catch (const std::exception&) { // Fails, ambiguous. } catch (...) { // Match. } return 0; }
2. Allows new exception designs and functionality. For instance, could add in exception classes such as re-throwable or concurrent, and use in more complex hierarchies instead of declaring subject-specific exception classes. Ie, instead of io_lock_error one could derive an io_error, that optionally had a concurrent_error.
struct base { virtual ~base() { } }; struct always_rethrow_error : virtual public base { }; struct concurrent_error : virtual public base { }; struct io_error : public concurrent_error, always_rethrow_error { }; int main() { try { throw io_error(); } catch (const base& obj) { try { throw; } catch (always_rethrow_error&) { throw; } catch (...) { // Other error handling, swallow. } } return 0; }
This example is but one demonstration (and not perhaps the best choice for determining if a particular exception is re-throwable).
what()
strings. All of the NTBS return values for exception::what()
are implementation-defined. This causes problems for portable code
that parses the returned string.
Baby steps toward this goal could include mandating that all return values start with the name of the most-derived exception class at construction, perhaps optionally followed by the explicitly qualified scope of the throw site. After that, the choices for messages start to diverge rapidly.
Nevertheless, just these simple steps would make text parsing of exception error messages possible in a portable way.
Integrate necessary changes for new C++0x components like
diagnostics and threads, and missing functionality. Two areas that
demand attention are: a mechanism for marking exception
objects as always re-thrown from catch
blocks, and a way
to map diagnostic/error numerical constants to the associated
exception classes (and back again.)
To mark exception objects as always-re-thrown, a variety of solutions exist. The first would be to add a member, say something like:
virtual const bool is_rethrown() const throw() { return true; }
A second option would be to use multiple inheritance to establish a base exception class that was re-throwable, and inherit from it for exceptions that are to be re-thrown. See the example above, in the discussion of Virtual derivation.
For the second issue, mapping diagnostic/error constants to
exception classes, possible solutions include adding a member function
to the exception base class, similar to what()
, but
instead returning the associated numerical constant. An example:
virtual const int value() const throw();
Another item in the solution space for the mapping issue would be to have a global map or function that takes an error code and returns an exception.
template<typename _Exception> _Exception use_exception(int error_code, std::string& msg);
This has the advantage that it could be extended by users by specialization, and would not take up space in the virtual table of a (more complicated) exception class hierarchy.
A more coherent include policy.
<system_error>
(or perhaps
<error_constants>
), as specified in N2303, minus
any exception classes, and in particular system_error
, as
it is subsumed into the expanded standard class hierarchies. If
possible, make only external dependency std::locale
forward declaration.
<exception>
(or perhaps
<exceptionfwd>
), containing C++03 contents, minus
any exception classes, with the one exception of the
exception_base
class. In addition, move
nothrow_t
from <new>
to this file. No
<string>
dependencies.
<stdexception>
, all derived exception classes
with <string>
dependencies, one-to-one match with
error constants detailed in <system_error>
. Current
exception classes scattered throughout C++0x include files would be
eliminated in favor of equivalent exception classes from the expanded
hierarchy, including bad_alloc
, bad_typeid
,
bad_cast
, bad_exception
,
bad_function_call
, and ios_base::failure
.
<exception_utils>
(or perhaps
<exceptionmanip>
), containing utilities for mapping
between exception and exception-free code, namely mapping between
error constants and the equivalent exception objects.
Please see the Appendix for example header files that implement the suggestions above.
catch
blocks: ending the swallowed exceptions practice.Some implementations of POSIX thread cancellation use the same frame unwind machinery as C++ exception handling implementations. Invariably, conflicts can occur. Sorting this out intelligently, so that both can co-exist is a matter of some debate.
Various solutions have been proposed.
1. Deprecating catch(...)
that doesn't re-throw. The
C++03 io code is notorious for this.
2. Changing catch(...)
to instead only catch exception
objects mandated in the standard, ie catch(const
std::exception&)
3. A magic internal exception type, that can be re-thrown by
relevant catch
blocks when encountered.
4. Suggestions have been made for a handler function, that would
make catch clauses re-throw. Or, in a similar vein, modifying member
functions like basic_ios::exceptions
that have a
user-controlled mechanism for determining if exceptions are ignored or
active, to also have a third state which controls re-throw behavior.
5. Deal with this in the catch
block, using properties
of the exception object being thrown and caught.
Whichever mechanism it picked, the entire C++0x library should be audited to make sure that the exception and error handling is consistent.
This involves the detailed implementation of a library-wide effort to do apply the above ideas.
All catch
statements would need to be evaluated. If
the exception object demanded to be re-thrown, then it would be (after
possibly setting some error state or condition in the host object or
associated area of said catch
statement.
The application of whatever solution was accepted for exception/exception-free code would have to be done, library-wide.
finally
.Ulrich Drepper, Pete Dimov, and other posters on the GNU libstdc++ mailing list.
Diagnostics Enhancements for C++0x (Rev. 1)
Diagnostics Enhancements; Resolution of Small Issues
Revised system_error (Revision 2)
Becker, Pete, Working Draft, Standard for Programming Language C++, N2284=07-0144
Abrahams, David, Error and Exception Handling
Stroustrup, Bjarne, The C++ Programming Language, v3. Chapter 14, Exception Handling.
Sutter, Herb, Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions, Chaper "Exception-Safety Issues and Techniques"
Sutter, Herb, More Exceptional C++, Chaper "Exception-Safety Issues and Techniques"
Gosling, Jame (Bill Joy, Guy Steele, Gilad Bracha), Java Language Specification, Third Edition
<system_error>
#ifndef _SYSTEM_ERROR #define _SYSTEM_ERROR 1 #include <cerrno> #include <locale> #include <typeinfo> namespace std { struct error_catalog { typedef int value_type; static const value_type address_family_not_supported = EAFNOSUPPORT; static const value_type address_in_use = EADDRINUSE; static const value_type address_not_available = EADDRNOTAVAIL; static const value_type already_connected = EISCONN; static const value_type argument_list_too_long = E2BIG; static const value_type argument_out_of_domain = EDOM; static const value_type bad_address = EFAULT; static const value_type bad_file_descriptor = EBADF; static const value_type bad_message = EBADMSG; static const value_type broken_pipe = EPIPE; static const value_type connection_aborted = ECONNABORTED; static const value_type connection_refused = ECONNREFUSED; static const value_type connection_reset = ECONNRESET; static const value_type cross_device_link = EXDEV; static const value_type destination_address_required = EDESTADDRREQ; static const value_type device_or_resource_busy = EBUSY; static const value_type directory_not_empty = ENOTEMPTY; static const value_type executable_format = ENOEXEC; static const value_type file_exists = EEXIST; static const value_type file_too_large = EFBIG; static const value_type filename_too_long = ENAMETOOLONG; static const value_type function_not_supported = ENOSYS; static const value_type host_unreachable = EHOSTUNREACH; static const value_type identifier_removed = EIDRM; static const value_type illegal_byte_sequence = EILSEQ; static const value_type inappropriate_io_control_operation = ENOTTY; static const value_type interrupted = EINTR; static const value_type invalid_argument = EINVAL; static const value_type invalid_seek = ESPIPE; static const value_type io = EIO; static const value_type is_a_directory = EISDIR; static const value_type message_too_long = EMSGSIZE; static const value_type network_down = ENETDOWN; static const value_type network_reset = ENETRESET; static const value_type network_unreachable = ENETUNREACH; static const value_type no_buffer_space = ENOBUFS; static const value_type no_child_process = ECHILD; static const value_type no_link = ENOLINK; static const value_type no_lock_available = ENOLCK; static const value_type no_message_available = ENODATA; static const value_type no_message = ENOMSG; static const value_type no_space_on_device = ENOSPC; static const value_type no_stream_resources = ENOSR; static const value_type no_such_device_or_address = ENXIO; static const value_type no_such_device = ENODEV; static const value_type no_such_file_or_directory = ENOENT; static const value_type no_such_process = ESRCH; static const value_type not_a_directory = ENOTDIR; static const value_type not_a_socket = ENOTSOCK; static const value_type not_a_stream = ENOSTR; static const value_type not_connected = ENOTCONN; static const value_type not_enough_memory = ENOMEM; static const value_type not_supported = ENOTSUP; static const value_type operation_canceled = ECANCELED; static const value_type operation_in_progress = EINPROGRESS; static const value_type operation_already_in_progress = EALREADY; static const value_type operation_not_permitted = EPERM; static const value_type operation_not_supported = EOPNOTSUPP; static const value_type owner_dead = EOWNERDEAD; static const value_type permission_denied = EACCES; static const value_type protocol = EPROTO; static const value_type protocol_not_available = ENOPROTOOPT; static const value_type protocol_not_supported = EPROTONOSUPPORT; static const value_type read_only_file_system = EROFS; static const value_type resource_deadlock_would_occur = EDEADLK; static const value_type result_out_of_range = ERANGE; static const value_type state_not_recoverable = ENOTRECOVERABLE; static const value_type stream_timeout = ETIME; static const value_type text_file_busy = ETXTBSY; static const value_type timed_out = ETIMEDOUT; static const value_type too_many_files_open_in_system = ENFILE; static const value_type too_many_files_open = EMFILE; static const value_type too_many_links = EMLINK; static const value_type too_many_synbolic_link_levels = ELOOP; static const value_type try_again = EAGAIN; static const value_type value_too_large = EOVERFLOW; static const value_type wrong_protocol_type = EPROTOTYPE; virtual const value_type last_value() const throw(); virtual bool is_valid_value(value_type) const throw(); virtual const char* str(value_type) const throw(); const locale& getloc() const { return _M_loc; } error_catalog(const char* __name) : _M_loc(__name) { locale::facet::_S_create_c_locale(_M_c_locale, __name); } error_catalog(const locale& __loc = locale::classic()) throw() : _M_loc(__loc) { locale::facet::_S_create_c_locale(_M_c_locale, __loc.name().c_str()); } virtual ~error_catalog() throw(); bool operator==(const error_catalog& __other) const throw() { bool __ret = getloc() == __other.getloc(); __ret &= typeid(*this) == typeid(__other); return __ret; } bool operator!=(const error_catalog& __other) const throw() { return !(*this == __other); } private: const locale _M_loc; }; } // namespace std #endif // _SYSTEM_ERROR
<exception>
#fndef _EXCEPTION #define _EXCEPTION 1 namespace std { typedef void (*terminate_handler) (); typedef void (*unexpected_handler) (); terminate_handler set_terminate(terminate_handler) throw(); unexpected_handler set_unexpected(unexpected_handler) throw(); void terminate(); void unexpected(); bool uncaught_exception() throw(); struct nothrow_t { }; extern const nothrow_t nothrow; // Abstract base type for exceptions with associated error // constants from system_error, but no embedded strings. struct exception_base { exception_base() throw() { } virtual ~exception_base() throw() = 0; virtual const bool is_rethrown() const throw() = 0; }; } // namespace std #endif // _EXCEPTION
<stdexception>
#ifndef _STDEXCEPT #define _STDEXCEPT 1 #include <string> namespace std { // Abstract base type for exceptions with embedded strings. struct exception: virtual public exception_base { exception(const string& s) throw() : _M_string(s) { } virtual ~exception() throw() { } virtual const string& str() const throw() = 0; virtual const bool is_rethrown() const throw() { return true; } private: string _M_string; }; // Here we go: all exception classes, in a flat hierarchy. struct address_family_not_supported_exception : virtual public exception { explicit address_family_not_supported_exception(const string& s) : exception(s) { } virtual ~address_family_not_supported_exception() throw() { } virtual const string& str() const throw(); }; struct address_in_use_exception : virtual public exception { explicit address_in_use_exception(const string& s) : exception(s) { } virtual ~address_in_use_exception() throw() { } virtual const string& str() const throw(); }; struct address_not_available_exception : virtual public exception { explicit address_not_available_exception(const string& s) : exception(s) { } virtual ~address_not_available_exception() throw() { } virtual const string& str() const throw(); }; struct already_connected_exception : virtual public exception { explicit already_connected_exception(const string& s) : exception(s) { } virtual ~already_connected_exception() throw() { } virtual const string& str() const throw(); }; struct argument_list_too_long_exception : virtual public exception { explicit argument_list_too_long_exception(const string& s) : exception(s) { } virtual ~argument_list_too_long_exception() throw() { } virtual const string& str() const throw(); }; struct argument_out_of_domain_exception : virtual public exception { explicit argument_out_of_domain_exception(const string& s) : exception(s) { } virtual ~argument_out_of_domain_exception() throw() { } virtual const string& str() const throw(); }; struct bad_address_exception : virtual public exception { explicit bad_address_exception(const string& s) : exception(s) { } virtual ~bad_address_exception() throw() { } virtual const string& str() const throw(); }; struct bad_file_descriptor_exception : virtual public exception { explicit bad_file_descriptor_exception(const string& s) : exception(s) { } virtual ~bad_file_descriptor_exception() throw() { } virtual const string& str() const throw(); }; struct bad_message_exception : virtual public exception { explicit bad_message_exception(const string& s) : exception(s) { } virtual ~bad_message_exception() throw() { } virtual const string& str() const throw(); }; struct broken_pipe_exception : virtual public exception { explicit broken_pipe_exception(const string& s) : exception(s) { } virtual ~broken_pipe_exception() throw() { } virtual const string& str() const throw(); }; struct connection_aborted_exception : virtual public exception { explicit connection_aborted_exception(const string& s) : exception(s) { } virtual ~connection_aborted_exception() throw() { } virtual const string& str() const throw(); }; struct connection_refused_exception : virtual public exception { explicit connection_refused_exception(const string& s) : exception(s) { } virtual ~connection_refused_exception() throw() { } virtual const string& str() const throw(); }; struct connection_reset_exception : virtual public exception { explicit connection_reset_exception(const string& s) : exception(s) { } virtual ~connection_reset_exception() throw() { } virtual const string& str() const throw(); }; struct cross_device_link_exception : virtual public exception { explicit cross_device_link_exception(const string& s) : exception(s) { } virtual ~cross_device_link_exception() throw() { } virtual const string& str() const throw(); }; struct destination_address_required_exception : virtual public exception { explicit destination_address_required_exception(const string& s) : exception(s) { } virtual ~destination_address_required_exception() throw() { } virtual const string& str() const throw(); }; struct device_or_resource_busy_exception : virtual public exception { explicit device_or_resource_busy_exception(const string& s) : exception(s) { } virtual ~device_or_resource_busy_exception() throw() { } virtual const string& str() const throw(); }; struct directory_not_empty_exception : virtual public exception { explicit directory_not_empty_exception(const string& s) : exception(s) { } virtual ~directory_not_empty_exception() throw() { } virtual const string& str() const throw(); }; struct executable_format_exception : virtual public exception { explicit executable_format_exception(const string& s) : exception(s) { } virtual ~executable_format_exception() throw() { } virtual const string& str() const throw(); }; struct file_exists_exception : virtual public exception { explicit file_exists_exception(const string& s) : exception(s) { } virtual ~file_exists_exception() throw() { } virtual const string& str() const throw(); }; struct file_too_large_exception : virtual public exception { explicit file_too_large_exception(const string& s) : exception(s) { } virtual ~file_too_large_exception() throw() { } virtual const string& str() const throw(); }; struct filename_too_long_exception : virtual public exception { explicit filename_too_long_exception(const string& s) : exception(s) { } virtual ~filename_too_long_exception() throw() { } virtual const string& str() const throw(); }; struct function_not_supportedexception : virtual public exception { explicit function_not_supportedexception(const string& s) : exception(s) { } virtual ~function_not_supportedexception() throw() { } virtual const string& str() const throw(); }; struct host_unreachable_exception : virtual public exception { explicit host_unreachable_exception(const string& s) : exception(s) { } virtual ~host_unreachable_exception() throw() { } virtual const string& str() const throw(); }; struct identifier_removed_exception : virtual public exception { explicit identifier_removed_exception(const string& s) : exception(s) { } virtual ~identifier_removed_exception() throw() { } virtual const string& str() const throw(); }; struct illegal_byte_sequence_exception : virtual public exception { explicit illegal_byte_sequence_exception(const string& s) : exception(s) { } virtual ~illegal_byte_sequence_exception() throw() { } virtual const string& str() const throw(); }; struct inappropriate_io_control_operation_exception : virtual public exception { explicit inappropriate_io_control_operation_exception(const string& s) : exception(s) { } virtual ~inappropriate_io_control_operation_exception() throw() { } virtual const string& str() const throw(); }; struct interrupted_exception : virtual public exception { explicit interrupted_exception(const string& s) : exception(s) { } virtual ~interrupted_exception() throw() { } virtual const string& str() const throw(); }; struct invalid_argument_exception : virtual public exception { explicit invalid_argument_exception(const string& s) : exception(s) { } virtual ~invalid_argument_exception() throw() { } virtual const string& str() const throw(); }; struct invalid_seek_exception : virtual public exception { explicit invalid_seek_exception(const string& s) : exception(s) { } virtual ~invalid_seek_exception() throw() { } virtual const string& str() const throw(); }; struct io_exception : virtual public exception { explicit io_exception(const string& s) : exception(s) { } virtual ~io_exception() throw() { } virtual const string& str() const throw(); }; struct is_a_directory_exception : virtual public exception { explicit is_a_directory_exception(const string& s) : exception(s) { } virtual ~is_a_directory_exception() throw() { } virtual const string& str() const throw(); }; struct message_too_long_exception : virtual public exception { explicit message_too_long_exception(const string& s) : exception(s) { } virtual ~message_too_long_exception() throw() { } virtual const string& str() const throw(); }; struct network_down_exception : virtual public exception { explicit network_down_exception(const string& s) : exception(s) { } virtual ~network_down_exception() throw() { } virtual const string& str() const throw(); }; struct network_reset_exception : virtual public exception { explicit network_reset_exception(const string& s) : exception(s) { } virtual ~network_reset_exception() throw() { } virtual const string& str() const throw(); }; struct network_unreachable_exception : virtual public exception { explicit network_unreachable_exception(const string& s) : exception(s) { } virtual ~network_unreachable_exception() throw() { } virtual const string& str() const throw(); }; struct no_buffer_space_exception : virtual public exception { explicit no_buffer_space_exception(const string& s) : exception(s) { } virtual ~no_buffer_space_exception() throw() { } virtual const string& str() const throw(); }; struct no_child_process_exception : virtual public exception { explicit no_child_process_exception(const string& s) : exception(s) { } virtual ~no_child_process_exception() throw() { } virtual const string& str() const throw(); }; struct no_link_exception : virtual public exception { explicit no_link_exception(const string& s) : exception(s) { } virtual ~no_link_exception() throw() { } virtual const string& str() const throw(); }; struct no_lock_available_exception : virtual public exception { explicit no_lock_available_exception(const string& s) : exception(s) { } virtual ~no_lock_available_exception() throw() { } virtual const string& str() const throw(); }; struct no_message_available_exception : virtual public exception { explicit no_message_available_exception(const string& s) : exception(s) { } virtual ~no_message_available_exception() throw() { } virtual const string& str() const throw(); }; struct no_message_exception : virtual public exception { explicit no_message_exception(const string& s) : exception(s) { } virtual ~no_message_exception() throw() { } virtual const string& str() const throw(); }; struct no_space_on_device_exception : virtual public exception { explicit no_space_on_device_exception(const string& s) : exception(s) { } virtual ~no_space_on_device_exception() throw() { } virtual const string& str() const throw(); }; struct no_stream_resources_exception : virtual public exception { explicit no_stream_resources_exception(const string& s) : exception(s) { } virtual ~no_stream_resources_exception() throw() { } virtual const string& str() const throw(); }; struct no_such_device_or_address_exception : virtual public exception { explicit no_such_device_or_address_exception(const string& s) : exception(s) { } virtual ~no_such_device_or_address_exception() throw() { } virtual const string& str() const throw(); }; struct no_such_device_exception : virtual public exception { explicit no_such_device_exception(const string& s) : exception(s) { } virtual ~no_such_device_exception() throw() { } virtual const string& str() const throw(); }; struct no_such_file_or_directory_exception : virtual public exception { explicit no_such_file_or_directory_exception(const string& s) : exception(s) { } virtual ~no_such_file_or_directory_exception() throw() { } virtual const string& str() const throw(); }; struct no_such_process_exception : virtual public exception { explicit no_such_process_exception(const string& s) : exception(s) { } virtual ~no_such_process_exception() throw() { } virtual const string& str() const throw(); }; struct not_a_directory_exception : virtual public exception { explicit not_a_directory_exception(const string& s) : exception(s) { } virtual ~not_a_directory_exception() throw() { } virtual const string& str() const throw(); }; struct not_a_socket_exception : virtual public exception { explicit not_a_socket_exception(const string& s) : exception(s) { } virtual ~not_a_socket_exception() throw() { } virtual const string& str() const throw(); }; struct not_a_stream_exception : virtual public exception { explicit not_a_stream_exception(const string& s) : exception(s) { } virtual ~not_a_stream_exception() throw() { } virtual const string& str() const throw(); }; struct not_connected_exception : virtual public exception { explicit not_connected_exception(const string& s) : exception(s) { } virtual ~not_connected_exception() throw() { } virtual const string& str() const throw(); }; struct not_enough_memory_exception : virtual public exception { explicit not_enough_memory_exception(const string& s) : exception(s) { } virtual ~not_enough_memory_exception() throw() { } virtual const string& str() const throw(); }; struct not_supported_exception : virtual public exception { explicit not_supported_exception(const string& s) : exception(s) { } virtual ~not_supported_exception() throw() { } virtual const string& str() const throw(); }; struct operation_canceled_exception : virtual public exception { explicit operation_canceled_exception(const string& s) : exception(s) { } virtual ~operation_canceled_exception() throw() { } virtual const string& str() const throw(); }; struct operation_in_progress_exception : virtual public exception { explicit operation_in_progress_exception(const string& s) : exception(s) { } virtual ~operation_in_progress_exception() throw() { } virtual const string& str() const throw(); }; struct operation_already_in_progress_exception : virtual public exception { explicit operation_already_in_progress_exception(const string& s) : exception(s) { } virtual ~operation_already_in_progress_exception() throw() { } virtual const string& str() const throw(); }; struct operation_no_permitted_exception : virtual public exception { explicit operation_no_permitted_exception(const string& s) : exception(s) { } virtual ~operation_no_permitted_exception() throw() { } virtual const string& str() const throw(); }; struct operation_not_supported_exception : virtual public exception { explicit operation_not_supported_exception(const string& s) : exception(s) { } virtual ~operation_not_supported_exception() throw() { } virtual const string& str() const throw(); }; struct owner_dead_exception : virtual public exception { explicit owner_dead_exception(const string& s) : exception(s) { } virtual ~owner_dead_exception() throw() { } virtual const string& str() const throw(); }; struct permission_denied_exception : virtual public exception { explicit permission_denied_exception(const string& s) : exception(s) { } virtual ~permission_denied_exception() throw() { } virtual const string& str() const throw(); }; struct protocol_exception : virtual public exception { explicit protocol_exception(const string& s) : exception(s) { } virtual ~protocol_exception() throw() { } virtual const string& str() const throw(); }; struct protocol_no_available_exception : virtual public exception { explicit protocol_no_available_exception(const string& s) : exception(s) { } virtual ~protocol_no_available_exception() throw() { } virtual const string& str() const throw(); }; struct protocol_not_supported_exception : virtual public exception { explicit protocol_not_supported_exception(const string& s) : exception(s) { } virtual ~protocol_not_supported_exception() throw() { } virtual const string& str() const throw(); }; struct read_only_file_system_exception : virtual public exception { explicit read_only_file_system_exception(const string& s) : exception(s) { } virtual ~read_only_file_system_exception() throw() { } virtual const string& str() const throw(); }; struct resource_deadlock_would_occur_exception : virtual public exception { explicit resource_deadlock_would_occur_exception(const string& s) : exception(s) { } virtual ~resource_deadlock_would_occur_exception() throw() { } virtual const string& str() const throw(); }; struct result_out_of_range_exception : virtual public exception { explicit result_out_of_range_exception(const string& s) : exception(s) { } virtual ~result_out_of_range_exception() throw() { } virtual const string& str() const throw(); }; struct state_not_recoverable_exception : virtual public exception { explicit state_not_recoverable_exception(const string& s) : exception(s) { } virtual ~state_not_recoverable_exception() throw() { } virtual const string& str() const throw(); }; struct stream_timeout_exception : virtual public exception { explicit stream_timeout_exception(const string& s) : exception(s) { } virtual ~stream_timeout_exception() throw() { } virtual const string& str() const throw(); }; struct text_file_busy_exception : virtual public exception { explicit text_file_busy_exception(const string& s) : exception(s) { } virtual ~text_file_busy_exception() throw() { } virtual const string& str() const throw(); }; struct timed_out_exception : virtual public exception { explicit timed_out_exception(const string& s) : exception(s) { } virtual ~timed_out_exception() throw() { } virtual const string& str() const throw(); }; struct too_many_files_open_in_system_exception : virtual public exception { explicit too_many_files_open_in_system_exception(const string& s) : exception(s) { } virtual ~too_many_files_open_in_system_exception() throw() { } virtual const string& str() const throw(); }; struct too_many_files_open_exception : virtual public exception { explicit too_many_files_open_exception(const string& s) : exception(s) { } virtual ~too_many_files_open_exception() throw() { } virtual const string& str() const throw(); }; struct too_many_links_exception : virtual public exception { explicit too_many_links_exception(const string& s) : exception(s) { } virtual ~too_many_links_exception() throw() { } virtual const string& str() const throw(); }; struct too_many_symbolic_link_levels_exception : virtual public exception { explicit too_many_symbolic_link_levels_exception(const string& s) : exception(s) { } virtual ~too_many_symbolic_link_levels_exception() throw() { } virtual const string& str() const throw(); }; struct try_again_exception : virtual public exception { explicit try_again_exception(const string& s) : exception(s) { } virtual ~try_again_exception() throw() { } virtual const string& str() const throw(); }; struct value_too_large_exception : virtual public exception { explicit value_too_large_exception(const string& s) : exception(s) { } virtual ~value_too_large_exception() throw() { } virtual const string& str() const throw(); }; struct wrong_protocol_type_exception : virtual public exception { explicit wrong_protocol_type_exception(const string& s) : exception(s) { } virtual ~wrong_protocol_type_exception() throw() { } virtual const string& str() const throw(); }; } // namespace std #endif // _STDEXCEPT
<exception_utils>
#ifndef _EXCEPTION_UTILS #define _EXCEPTION_UTILS 1 #include <system_error> #include <stdexcept> namespace std { template<typename _Exception> _Exception use_exception(int, std::string& msg); // If exceptions, throws via use_exception(value), if not, sets error. void raise_error(int& toset, const int value); // Never void raise_error(int& toset, const int value, const nothrow_t&); } // namespace std #endif // _EXCEPTION_UTILS