Q_DECL_NOTHROW: stronger and more widely available version of Q_DECL_NOEXCEPT
Commit 1adca807 defined Q_DECL_NOEXCEPT to be the same as throw() for the Microsoft compiler. However, the two are not equivalent: - C++11 noexcept is defined to call std::terminate() if a noexcept function nevertheless encounters an exception. - MSVC throw() has essentially undefined behaviour in this situation: http://msdn.microsoft.com/en-us/library/wfa0edys%28v=vs.100%29 "Due to code optimizations that might be performed by the C++ compiler [...] if a function does throw an exception, the program may not execute correctly." So define two macros: 1. Q_DECL_NOEXCEPT/Q_DECL_NOEXCEPT_EXPR always have C++11 behaviour. This is expected to be the more efficient implementation if the function can actually throw. 2. Q_DECL_NOTHROW means that the function gives the nothrow guarantee. It is stronger than noexcept, but not all functions that can be marked Q_DECL_NOEXCEPT can be marked Q_DECL_NOTHROW. In general Q_DECL_NOTHROW functions need to use a try/catch block in order to prevent exceptions from leaving the functions, unless you can proove that none of the operations can throw. For the caller, both macros are equivalent: it can be relied on that no exception leaves the function. Change-Id: I32f822a82e06a31cb71d38db438387aee5ec3334 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
This commit is contained in:
parent
46212d657e
commit
f829ab5573
@ -110,9 +110,9 @@
|
||||
# define Q_COMPILER_VARIADIC_MACROS
|
||||
# endif
|
||||
|
||||
// make sure that these aren't defined when Q_COMPILER_NOEXCEPT is defined
|
||||
# define Q_DECL_NOEXCEPT throw()
|
||||
# define Q_DECL_NOEXCEPT_EXPR(x)
|
||||
/* only defined for MSVC since that's the only compiler that actually optimizes for this */
|
||||
/* might get overridden further down when Q_COMPILER_NOEXCEPT is detected */
|
||||
# define Q_DECL_NOTHROW throw()
|
||||
|
||||
#elif defined(__BORLANDC__) || defined(__TURBOC__)
|
||||
# define Q_CC_BOR
|
||||
@ -717,10 +717,16 @@
|
||||
#ifdef Q_COMPILER_NOEXCEPT
|
||||
# define Q_DECL_NOEXCEPT noexcept
|
||||
# define Q_DECL_NOEXCEPT_EXPR(x) noexcept(x)
|
||||
#elif !defined(Q_DECL_NOEXCEPT)
|
||||
# ifdef Q_DECL_NOTHROW
|
||||
# undef Q_DECL_NOTHROW /* override with C++11 noexcept if available */
|
||||
# endif
|
||||
#else
|
||||
# define Q_DECL_NOEXCEPT
|
||||
# define Q_DECL_NOEXCEPT_EXPR(x)
|
||||
#endif
|
||||
#ifndef Q_DECL_NOTHROW
|
||||
# define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
|
||||
# define Q_ALIGNOF(x) alignof(x)
|
||||
|
@ -3014,4 +3014,67 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
|
||||
otherwise.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro Q_DECL_NOTHROW
|
||||
\relates <QtGlobal>
|
||||
\since 5.0
|
||||
|
||||
This macro marks a function as never throwing, under no
|
||||
circumstances. If the function does nevertheless throw, the
|
||||
behaviour is undefined.
|
||||
|
||||
The macro expands to either "throw()", if that has some benefit on
|
||||
the compiler, or to C++11 noexcept, if available, or to nothing
|
||||
otherwise.
|
||||
|
||||
If you need C++11 noexcept semantics, don't use this macro, use
|
||||
Q_DECL_NOEXCEPT/Q_DECL_NOEXCEPT_EXPR instead.
|
||||
|
||||
\sa Q_DECL_NOEXCEPT, Q_DECL_NOEXCEPT_EXPR
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro Q_DECL_NOEXCEPT
|
||||
\relates <QtGlobal>
|
||||
\since 5.0
|
||||
|
||||
This macro marks a function as never throwing. If the function
|
||||
does nevertheless throw, the behaviour is defined:
|
||||
std::terminate() is called.
|
||||
|
||||
The macro expands to C++11 noexcept, if available, or to nothing
|
||||
otherwise.
|
||||
|
||||
If you need the operator version of C++11 noexcept, use
|
||||
Q_DECL_NOEXCEPT_EXPR(x).
|
||||
|
||||
If you don't need C++11 noexcept semantics, e.g. because your
|
||||
function can't possibly throw, don't use this macro, use
|
||||
Q_DECL_NOTHROW instead.
|
||||
|
||||
\sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT_EXPR
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro Q_DECL_NOEXCEPT_EXPR(x)
|
||||
\relates <QtGlobal>
|
||||
\since 5.0
|
||||
|
||||
This macro marks a function as non-throwing if \a x is true. If
|
||||
the function does nevertheless throw, the behaviour is defined:
|
||||
std::terminate() is called.
|
||||
|
||||
The macro expands to C++11 noexcept(x), if available, or to
|
||||
nothing otherwise.
|
||||
|
||||
If you need the always-true version of C++11 noexcept, use
|
||||
Q_DECL_NOEXCEPT.
|
||||
|
||||
If you don't need C++11 noexcept semantics, e.g. because your
|
||||
function can't possibly throw, don't use this macro, use
|
||||
Q_DECL_NOTHROW instead.
|
||||
|
||||
\sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT_EXPR
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
x
Reference in New Issue
Block a user