Difference between C++03 throw() specifier C++11 noexcept

C++ExceptionC++11ThrowNoexcept

C++ Problem Overview


Is there any difference between throw() and noexcept other than being checked at runtime and compile time, respectively?

This Wikipedia C++11 article suggests that the C++03 throw specifiers are deprecated.
Why so, is noexcept capable enough to cover all that at compile time ?

[Note: I checked this question and this article, but couldn't determine the solid reason for deprecation.]

C++ Solutions


Solution 1 - C++

Exception specifiers were deprecated because exception specifiers are generally a terrible idea. noexcept was added because it's the one reasonably useful use of an exception specifier: knowing when a function won't throw an exception. Thus it becomes a binary choice: functions that will throw and functions that won't throw.

noexcept was added rather than just removing all throw specifiers other than throw() because noexcept is more powerful. noexcept can have a parameter which compile-time resolves into a boolean. If the boolean is true, then the noexcept sticks. If the boolean is false, then the noexcept doesn't stick and the function may throw.

Thus, you can do something like this:

struct<typename T>
{
  void CreateOtherClass() { T t{}; }
};

Does CreateOtherClass throw exceptions? It might, if T's default constructor can. How do we tell? Like this:

struct<typename T>
{
  void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};

Thus, CreateOtherClass() will throw iff the given type's default constructor throws. This fixes one of the major problems with exception specifiers: their inability to propagate up the call stack.

You can't do this with throw().

Solution 2 - C++

noexcept isn't checked at compile time.

> An implementation shall not reject an expression merely because when executed it throws or might throw an exception that the containing function does not allow.

When a function that is declared noexcept or throw() attempts to throw an exception the only difference is that one calls terminate and the othe calls unexpected and the latter style of exception handling has effectively been deprecated.

Solution 3 - C++

std::unexpected() is called by the C++ runtime when a dynamic exception specification is violated: an exception is thrown from a function whose exception specification forbids exceptions of this type.

std::unexpected() may also be called directly from the program.

In either case, std::unexpected calls the currently installed std::unexpected_handler. The default std::unexpected_handler calls std::terminate.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioniammilindView Question on Stackoverflow
Solution 1 - C++Nicol BolasView Answer on Stackoverflow
Solution 2 - C++CB BaileyView Answer on Stackoverflow
Solution 3 - C++ma13View Answer on Stackoverflow