]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Reorganize the exception handling in exception.h, remove noexcept(false) annotations...
authormaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 22 Oct 2013 08:36:27 +0000 (08:36 +0000)
committermaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 22 Oct 2013 08:36:27 +0000 (08:36 +0000)
 * Provide an AssertNothrow macro that does behave exactly like Assert,
   except that if disable_abort_on_exception was called, it merely prints
   the exception name and continues normally (instead of throwing the
   exception).

 * Use AssertNothrow in ~Subscriptor and ~GrowingVectorMemory to avoid an
   unexpected call to std::terminate in C++11 mode

 * Remove noexcept(false) from the library because this seriously
   inconvenients the user

git-svn-id: https://svn.dealii.org/trunk@31378 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/include/deal.II/base/exceptions.h
deal.II/include/deal.II/base/function_time.h
deal.II/include/deal.II/base/subscriptor.h
deal.II/source/base/exceptions.cc
deal.II/source/base/subscriptor.cc
deal.II/source/lac/vector_memory.cc

index ffea72d31a8a26dc22a0a9c91cddf4e1aae875d6..3ac055a0ac410ede2111aa2ad6e34f746d66a5df 100644 (file)
@@ -198,41 +198,40 @@ namespace deal_II_exceptions
   {
 
     /**
-     * Conditionally abort the program. Depending on whether
-     * disable_abort_on_exception was called, this function either aborts
-     * the program flow by printing the error message provided by @p exc
-     * and calling <tt>std::abort()</tt>, or throws @p exc instead.
+     * Conditionally abort the program.
+     *
+     * Depending on whether disable_abort_on_exception was called, this
+     * function either aborts the program flow by printing the error
+     * message provided by @p exc and calling <tt>std::abort()</tt>, or
+     * throws @p exc instead (if @p nothrow is set to <tt>false</tt>).
+     *
+     * If the boolean @p nothrow is set to true and
+     * disable_abort_on_exception was called, the exception type is just
+     * printed to deallog and program flow continues. This is useful if
+     * throwing an exception is prohibited (e.g. in a destructor with
+     * <tt>noexcept(true)</tt> or <tt>throw()</tt>).
      */
-    void abort (const ExceptionBase &exc);
+    void abort (const ExceptionBase &exc, bool nothrow = false);
 
     /**
-     * This routine does the main work for the exception generation
-     * mechanism used in the <tt>Assert</tt> macro.
-     *
-     * @ref ExceptionBase
+     * An enum describing how to treat an exception in issue_error
      */
-    template <class exc>
-    void issue_error_abort (const char *file,
-                            int         line,
-                            const char *function,
-                            const char *cond,
-                            const char *exc_name,
-                            exc         e)
+    enum ExceptionHandling
     {
-      // Fill the fields of the exception object
-      e.set_fields (file, line, function, cond, exc_name);
-
-      dealii::deal_II_exceptions::internals::abort(e);
-    }
+      abort_on_exception,
+      throw_on_exception,
+      abort_nothrow_on_exception
+    };
 
     /**
      * This routine does the main work for the exception generation
-     * mechanism used in the <tt>AssertThrow</tt> macro.
+     * mechanism used in the <tt>Assert</tt> macro.
      *
      * @ref ExceptionBase
      */
     template <class exc>
-    void issue_error (const char *file,
+    void issue_error (ExceptionHandling handling,
+                      const char *file,
                       int         line,
                       const char *function,
                       const char *cond,
@@ -241,7 +240,18 @@ namespace deal_II_exceptions
     {
       // Fill the fields of the exception object
       e.set_fields (file, line, function, cond, exc_name);
-      throw e;
+
+      switch(handling)
+        {
+        case abort_on_exception:
+          dealii::deal_II_exceptions::internals::abort(e);
+          break;
+        case abort_nothrow_on_exception:
+          dealii::deal_II_exceptions::internals::abort(e, /*nothrow =*/ true);
+          break;
+        case throw_on_exception:
+          throw e;
+        }
     }
 
   } /*namespace internals*/
@@ -261,18 +271,45 @@ namespace deal_II_exceptions
  * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
  */
 #ifdef DEBUG
-#define Assert(cond, exc)                                                 \
-  {                                                                       \
-    if (!(cond))                                                          \
-      ::dealii::deal_II_exceptions::internals::                           \
-      issue_error_abort (__FILE__,                                        \
-                         __LINE__,                                        \
-                         __PRETTY_FUNCTION__, #cond, #exc, exc);          \
-  }
+#define Assert(cond, exc)                                                   \
+{                                                                           \
+  if (!(cond))                                                              \
+    ::dealii::deal_II_exceptions::internals::                               \
+    issue_error(::dealii::deal_II_exceptions::internals::abort_on_exception,\
+                __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
+}
+#else
+#define Assert(cond, exc)                                                   \
+{}
+#endif
+
 
+
+/**
+ * A variant of the <tt>Assert</tt> macro above that exhibits the same
+ * runtime behaviour as long as disable_abort_on_exception was not called.
+ *
+ * However, if disable_abort_on_exception was called, this macro merely
+ * prints the exception that would be thrown to deallog and continues
+ * normally without throwing an exception.
+ *
+ * See the <tt>ExceptionBase</tt> class for more information.
+ *
+ * @ingroup Exceptions
+ * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
+ */
+#ifdef DEBUG
+#define AssertNothrow(cond, exc)                                            \
+{                                                                           \
+  if (!(cond))                                                              \
+    ::dealii::deal_II_exceptions::internals::                               \
+    issue_error(                                                            \
+      ::dealii::deal_II_exceptions::internals::abort_nothrow_on_exception,  \
+      __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc);           \
+}
 #else
-#define Assert(cond, exc)                                                 \
-  { }
+#define AssertNothrow(cond, exc)                                            \
+{}
 #endif
 
 
@@ -289,24 +326,21 @@ namespace deal_II_exceptions
  * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
  */
 #ifdef HAVE_BUILTIN_EXPECT
-#define AssertThrow(cond, exc)                                            \
-  {                                                                       \
-    if (__builtin_expect(!(cond), false))                                 \
-      ::dealii::deal_II_exceptions::internals::                           \
-      issue_error (__FILE__,                                              \
-                   __LINE__,                                              \
-                   __PRETTY_FUNCTION__, #cond, #exc, exc);                \
-  }
-
+#define AssertThrow(cond, exc)                                              \
+{                                                                           \
+  if (__builtin_expect(!(cond), false))                                     \
+    ::dealii::deal_II_exceptions::internals::                               \
+    issue_error(::dealii::deal_II_exceptions::internals::throw_on_exception,\
+                __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
+}
 #else /*ifdef HAVE_BUILTIN_EXPECT*/
-#define AssertThrow(cond, exc)                                            \
-  {                                                                       \
-    if (!(cond))                                                          \
-      ::dealii::deal_II_exceptions::internals::                           \
-      issue_error (__FILE__,                                              \
-                   __LINE__,                                              \
-                   __PRETTY_FUNCTION__, #cond, #exc, exc);                \
-  }
+#define AssertThrow(cond, exc)                                              \
+{                                                                           \
+  if (!(cond))                                                              \
+    ::dealii::deal_II_exceptions::internals::                               \
+    issue_error(::dealii::deal_II_exceptions::internals::throw_on_exception,\
+                __FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #exc, exc); \
+}
 #endif /*ifdef HAVE_BUILTIN_EXPECT*/
 
 
index 2b17d0f29fc410490a8b1ac67abb29f95c0a4df4..3615f51f73a30042aec1c31a20d3dec39c4824aa 100644 (file)
@@ -77,11 +77,7 @@ public:
   /**
    * Virtual destructor.
    */
-#ifdef DEAL_II_USE_CXX11
-  virtual ~FunctionTime() noexcept(false);
-#else
   virtual ~FunctionTime();
-#endif
 
   /**
    * Return the value of the time variable/
index d546c876e8fdbc9111893f2b509020cda7a65599..44d425865c4bf61a6f85fff08b5a2a867efe580c 100644 (file)
@@ -75,17 +75,7 @@ public:
    * Destructor, asserting that the counter
    * is zero.
    */
-#ifdef DEAL_II_USE_CXX11
-  // According to the C++11 standard [class.dtor] 3 in combination with
-  // [except.spec] 14 and [except.spec] 9---as explained in detail in
-  // [1]---we're guilty of just terminating in case of throwing an
-  // exception in ~Subscriptor if we do not annotate it with
-  // "noexcept(false)"
-  // [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3204.htm
-  virtual ~Subscriptor() noexcept(false);
-#else
   virtual ~Subscriptor();
-#endif
 
   /**
    * Assignment operator.
index 89350862fc7fc47bdba77836239f0a44c99c0f77..28638e85014eeeaedc1b85ef4578740243feab03 100644 (file)
@@ -281,16 +281,26 @@ namespace deal_II_exceptions
   namespace internals
   {
 
-    void abort (const ExceptionBase &exc)
+    void abort (const ExceptionBase &exc, bool nothrow /*= false*/)
     {
       if (dealii::deal_II_exceptions::abort_on_exception)
         {
-          //* Print the error message and bail out:
+          // Print the error message and bail out:
           std::cerr << exc.what() << std::endl;
           std::abort();
         }
+      else if (nothrow)
+        {
+          // We are not allowed to throw, and not allowed to abort.
+          // Just print the exception name to deallog and continue
+          // normally:
+          deallog << "Exception: " << e.get_exc_name() << std::endl;
+        }
       else
         {
+          // We are not allowed to abort, so just throw the error so just
+          // throw the error so just throw the error so just throw the
+          // error:
           throw exc;
         }
     }
index b9af279a917df3a54fdd4195fb2bc3eae9a81262..bc039582d72f41aab37aef58ebc3842eed4d58d5 100644 (file)
@@ -57,11 +57,7 @@ Subscriptor::Subscriptor (const Subscriptor &)
 {}
 
 
-#ifdef DEAL_II_USE_CXX11
-Subscriptor::~Subscriptor () noexcept(false)
-#else
 Subscriptor::~Subscriptor ()
-#endif
 {
   // check whether there are still
   // subscriptions to this object. if
@@ -109,8 +105,8 @@ Subscriptor::~Subscriptor ()
           if (infostring == "")
             infostring = "<none>";
 
-          Assert (counter == 0,
-                  ExcInUse (counter, object_info->name(), infostring));
+          AssertNothrow (counter == 0,
+                         ExcInUse (counter, object_info->name(), infostring));
         }
       else
         {
index 6ada53b04ccffd141c5a2a48c91b5ab0049ab5df..34483b9aa9d15a51b954c19203f94416af7d1885 100644 (file)
@@ -108,8 +108,8 @@ GrowingVectorMemory<VECTOR>::~GrowingVectorMemory() noexcept(false)
 GrowingVectorMemory<VECTOR>::~GrowingVectorMemory()
 #endif
 {
-  AssertThrow(current_alloc == 0,
-              StandardExceptions::ExcMemoryLeak(current_alloc));
+  AssertNothrow(current_alloc == 0,
+                StandardExceptions::ExcMemoryLeak(current_alloc));
   if (log_statistics)
     {
       deallog << "GrowingVectorMemory:Overall allocated vectors: "

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.