summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qcompilerdetection.h
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-08-07 01:54:13 +0200
committerQt by Nokia <qt-info@nokia.com>2012-08-07 21:11:55 +0200
commitf829ab5573f7146785c79d83182757043b0e6ce9 (patch)
treebf164c6f38044de5df0e5dde19ab8cae84bb9e7b /src/corelib/global/qcompilerdetection.h
parent46212d657e2e989dddd361a732e65b05748e8e91 (diff)
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>
Diffstat (limited to 'src/corelib/global/qcompilerdetection.h')
-rw-r--r--src/corelib/global/qcompilerdetection.h14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 64aae8acb2..be167f2a2a 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -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)