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

iammilind picture iammilind · Oct 11, 2012 · Viewed 24.2k times · Source

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

Answer

Nicol Bolas picture Nicol Bolas · Oct 11, 2012

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().