[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-------
- [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/23
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Greg Chicares, 2018/03/23
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/24
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Greg Chicares, 2018/03/24
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/24
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Greg Chicares, 2018/03/25
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/25
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Greg Chicares, 2018/03/25
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/26
- Re: [lmi] PATCH: use std::uncaught_exceptions(),
Greg Chicares <=
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/27
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Greg Chicares, 2018/03/29
- Re: [lmi] PATCH: use std::uncaught_exceptions(), Vadim Zeitlin, 2018/03/31
- [lmi] progress_meter dtor verifies postcondition [Was: PATCH: use std::uncaught_exceptions()], Greg Chicares, 2018/03/31