Good stuff, the standard is confusing indeed, but that link is gold @matt.mccormick.
So, sharing a wrapping up from the link and cppreference.
- Since c++17:
throw()
and noexcept
, (i.e, the specifier: noexcept(true)
) are exactly the same.
- Pre c++17,
throw()
calls std::unexpected
instead of std::terminate
if the function generates a exception. throw
specifier is deprecated since c++11.
Also noexcept
tagged functions can be checked at compile time with the noexcept
operator: noexcept(myfunction)
.
Note the reason of this post: the dynamic exception specification: throw(type_id, type_id,…) is deprecated since c++11 and has no noexcept
equivalent.
From: noexcept specifier (since C++11) - cppreference.com
noexcept is an improved version of throw(), which is deprecated in C++11. Unlike pre-C++17 throw(), noexcept will not call std::unexpected and may or may not unwind the stack, which potentially allows the compiler to implement noexcept without the runtime overhead of throw().
- c++03: there is no
noexcept
--specifier or operator–, we use the throw()
specifier.
Proposition:
Remove deprecate ITK_NOEXCEPT_OR_THROW
and use a modified ITK_NOEXCEPT
:
From itk_compiler_detection: ITK_NOEXCEPT_EXPR(X)
is not used anywhere in ITK (after a fast grep), there is no similar functionality to the noexcept operator
in c++03. And the valid specifier with X=false
: noexcept(false)
is already the default for every function.
Also ITK_NOEXCEPT
does nothing right know in old compilers, when throw()
could be used instead
# if ITK_COMPILER_CXX_NOEXCEPT
# define ITK_NOEXCEPT noexcept
# define ITK_NOEXCEPT_EXPR(X) noexcept(X)
# else
# define ITK_NOEXCEPT
# define ITK_NOEXCEPT_EXPR(X)
# endif
I propose to deprecate ITK_NOEXCEPT_EXPR as well, and directly use the operator noexcept(expr)
when c++11 is allowed. Right now it can generate invalid code for c++03. From:
if( ITK_NOEXCEPT_EXPR(no_throw_function()) )
/* valid c++11:
* if( noexcept(no_throw_function()) ) // true
* invalid c++03
* if()
*/
So rename duplicate the macro from itkMacro.h, to deal with the noexcept
specifier.
#if ITK_COMPILER_CXX_NOEXCEPT
#define ITK_NOEXCEPT noexcept
#else
#define ITK_NOEXCEPT throw()
#endif
Edited:
Change ITK_NOEXCEPT to have same behavior than ITK_NOEXCEPT_OR_THROW, and deprecate the latter.
Remove ITK_NOEXCEPT from almost everywhere (destructors included), except low-level function such as Swap
, Unregister
etc.