Are dynamic exception specifications invalid in c++17?
General C++ guidelines discourages to use of exception specifications with any version of C++ and new standard has removed this feature.
E.30: Don't use exception specifications
ReasonException specifications make error handling brittle, impose a run-time cost, and have been removed from the C++ standard.
Exampleint use(int arg) throw(X, Y) { // ... auto x = f(arg); // ... }
If
f()
throws an exception different fromX
andY
the unexpected handler is invoked, which by default terminates. That's OK, but say that we have checked that this cannot happen andf
is changed to throw a new exceptionZ
, we now have a crash on our hands unless we changeuse()
(and re-test everything). The snag is thatf()
may be in a library we do not control and the new exception is not anything thatuse()
can do anything about or is in any way interested in. We can changeuse()
to passZ
through, but nowuse()
's callers probably needs to be modified. This quickly becomes unmanageable. Alternatively, we can add atry
-catch
touse()
to mapZ
into an acceptable exception. This too, quickly becomes unmanageable. Note that changes to the set of exceptions often happens at the lowest level of a system (e.g., because of changes to a network library or some middleware), so changes "bubble up" through long call chains. In a large code base, this could mean that nobody could update to a new version of a library until the last user was modified. Ifuse()
is part of a library, it may not be possible to update it because a change could affect unknown clients.The policy of letting exceptions propagate until they reach a function that potentially can handle it has proven itself over the years.
NoteNo. This would not be any better had exception specifications been statically enforced. For example, see Stroustrup94.
NoteIf no exception may be thrown, use
noexcept
or its equivalentthrow()
.
They are officially invalid in C++17. However, Visual C++17 with C++/Language/C++ Language Standard set to ISO C++17 still allows them. Setting warning level to 3 or higher [properties/General/Warning Level/] gives the warning,
warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
Note that throw() is still legal and is equivalent to the newly added noexcept.