lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] PATCH: use std::uncaught_exceptions()


From: Greg Chicares
Subject: Re: [lmi] PATCH: use std::uncaught_exceptions()
Date: Tue, 27 Mar 2018 11:04:08 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

On 2018-03-26 15:47, Vadim Zeitlin wrote:
> On Sun, 25 Mar 2018 23:30:06 +0000 Greg Chicares <address@hidden> wrote:
[...]
> GC> I tried implementing it myself. I'm sure you could do it faster, but by
> GC> doing it myself I might grow comfortable with the technique.

Here are the results of my further experiments. First of all, if we
erroneously fail to make the base-class dtor 'noexcept(false)', then
throwing in the derived-class dtor must call terminate(). But I want
to see for myself...

+        if(true && !std::uncaught_exceptions())
             {
+//          throw "oops"; // error: throw will always call terminate()
-            warning()
+            alarum() // Abnormal-termination handler called.

Even when guarded with "if(!std::uncaught_exceptions())":
 - a literal "throw" is diagnosed at compile time;
 - using alarum() instead of warning() ensures that an exception
   will be thrown, but gcc doesn't know that, so compilation
   succeeds...and lmi_terminate_handler() is called at run time.
No surprise, so far.

However, if I apply your patch with further modifications, thus:

---------8<--------8<--------8<--------8<--------8<--------8<--------8<-------
diff --git a/ledger_pdf_generator_wx.cpp b/ledger_pdf_generator_wx.cpp
index 20a48256..6f5e955c 100644
--- a/ledger_pdf_generator_wx.cpp
+++ b/ledger_pdf_generator_wx.cpp
@@ -655,7 +655,7 @@ class page
     page& operator=(page const&) = delete;
 
     // Make base class dtor virtual.
-    virtual ~page() = default;
+    virtual ~page() noexcept(false) {}
 
     // Associate the illustration object using this page with it.
     //
@@ -1165,6 +1165,7 @@ class numbered_page : public page_with_footer
 
     numbered_page()
     {
+//      alarum() << "Simulate error." << LMI_FLUSH; // Trapped by lmi. (1)
         // This assert would fail if start_numbering() hadn't been called
         // before creating a numbered page, as it should be.
         LMI_ASSERT(0 <= last_page_number_);
@@ -1191,7 +1192,7 @@ class numbered_page : public page_with_footer
         last_page_number_ += extra_pages_;
     }
 
-    ~numbered_page() override
+    ~numbered_page() noexcept(false) override
     {
         // Check that next_page() was called the expected number of times,
         // unless we're unwinding the stack due to some other error, in which
@@ -1199,9 +1200,10 @@ class numbered_page : public page_with_footer
         //
         // Notice that we shouldn't use LMI_ASSERT() in the dtor by default,
         // and it's better to use warning() instead of using noexcept(false).
-        if(extra_pages_ && !std::uncaught_exceptions())
+        if(true && !std::uncaught_exceptions())
             {
-            warning()
+//          throw "xyzzy"; // Builds okay; calls terminate handler. (2)
+            alarum() // Same: Builds okay; calls terminate handler. (3)
                 << "Logic error: there should have been "
                 << extra_pages_
                 << " more page(s) after the page "
--------->8-------->8-------->8-------->8-------->8-------->8-------->8-------

...then it doesn't seem to do what we hope. Referring to certain changed
lines by the parenthesized numbers at their ends:

(1) alarum() in the ctor throws an exception that is caught in the normal
orderly fashion, displaying its "Simulate error." message.

(2) 'throw'  in the dtor calls lmi_terminate_handler().

(3) alarum() in the dtor calls lmi_terminate_handler().

AIUI, we were expecting that (2) and (3) would have much the same effect
as (1), throwing an exception that we could catch and handle, but instead
they terminate lmi abruptly: any unsaved work is lost, and the diagnostic
information ("should have been N more page(s)") is not displayed. Is this
a gcc defect?

Just to make sure that we really are trapping that exception to the extent
possible, I surrounded the call to write_ledger_as_pdf() with try...catch,
which didn't make any difference:

---------8<--------8<--------8<--------8<--------8<--------8<--------8<-------
diff --git a/emit_ledger.cpp b/emit_ledger.cpp
index 2dddb93f..c734f24f 100644
--- a/emit_ledger.cpp
+++ b/emit_ledger.cpp
@@ -23,6 +23,7 @@
 
 #include "emit_ledger.hpp"
 
+#include "alert.hpp"                    // safely_show_message()
 #include "assert_lmi.hpp"
 #include "configurable_settings.hpp"
 #include "custom_io_0.hpp"
@@ -106,6 +107,8 @@ double ledger_emitter::emit_cell
         goto done;
         }
 
+  try
+    {
     if(emission_ & mce_emit_pdf_file)
         {
         write_ledger_as_pdf(ledger, cell_filepath);
@@ -164,6 +167,11 @@ double ledger_emitter::emit_cell
             ;
         custom_io_1_write(ledger, out_file.string());
         }
+    }
+  catch(...)
+    {
+    safely_show_message("caught something");
+    }
 
   done:
     return timer.stop().elapsed_seconds();
--------->8-------->8-------->8-------->8-------->8-------->8-------->8-------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]