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: Sun, 25 Mar 2018 23:30:06 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

On 2018-03-25 16:40, Vadim Zeitlin wrote:
> On Sun, 25 Mar 2018 16:10:24 +0000 Greg Chicares <address@hidden> wrote:
> 
> GC> Let's establish the premises first.
> GC> 
> GC> (1) AIUI, PDF files are generated something like this:
> GC>   (a) create PDF file for output
> GC>   (b) append stuff: b1, b2, b3...
> GC>   (c) close the file
> GC> and it's my impression that any error in (b) leaves a file that may
> GC> be syntactically valid. For example, I've seen the wxPdfDoc code
> GC> create PDF files that can be opened in a PDF viewer but appear to
> GC> have no contents.
[...]
>  You're correct, but I've actually realized that uncaught_exceptions()
> could be really helpful here, as the PDF file is actually written to when
> wxPdfDC::EndDoc() is called and we currently do this in pdf_writer_wx dtor
> unconditionally. We could, however, check whether we're in the process of
> stack unwinding and not do it then, which would avoid touching anything on
> disk in case of an error.

I took a nap after writing my previous message in this thread, and awoke
feeling that we might be able to put this magic to good use in this case.
That glow faded quickly...

>  To summarize, my preferred solution would be to continue calling EndDoc()
> from the dtor automatically, but skip doing it during stack unwinding.

I tried implementing it myself. I'm sure you could do it faster, but by
doing it myself I might grow comfortable with the technique. Here's
what I tried: of four hunks changed, I really only want the last two,
and the first two are just my failed attempts to fix the errors.

---------8<--------8<--------8<--------8<--------8<--------8<--------8<-------
diff --git a/ledger_pdf_generator_wx.cpp b/ledger_pdf_generator_wx.cpp
index 20a48256..37415d0f 100644
--- a/ledger_pdf_generator_wx.cpp
+++ b/ledger_pdf_generator_wx.cpp
@@ -655,7 +655,8 @@ class page
     page& operator=(page const&) = delete;
 
     // Make base class dtor virtual.
-    virtual ~page() = default;
+    // need "noexcept(false)" here for ~numbered_page() to throw
+    virtual ~page() noexcept(false) = default;
 
     // Associate the illustration object using this page with it.
     //
@@ -994,6 +995,11 @@ class cover_page : public page
 class page_with_footer : public page
 {
   public:
+    // need explicit dtor here, else:
+    //   error: non-deleted function ~numbered_page()
+    //   overriding deleted function ~page_with_footer()
+    ~page_with_footer() override = default;
+
     // Override pre_render() to compute footer_top_ which is needed in the
     // derived classes overridden get_extra_pages_needed().
     void pre_render
@@ -1191,6 +1197,9 @@ class numbered_page : public page_with_footer
         last_page_number_ += extra_pages_;
     }
 
+// Can't just add "noexcept(false)":
+//  ~numbered_page() noexcept(false) override
+// because that gives "error: looser throw specifier"
     ~numbered_page() override
     {
         // Check that next_page() was called the expected number of times,
diff --git a/pdf_writer_wx.cpp b/pdf_writer_wx.cpp
index d68d5318..907f24af 100644
--- a/pdf_writer_wx.cpp
+++ b/pdf_writer_wx.cpp
@@ -244,5 +244,6 @@ int pdf_writer_wx::get_page_bottom() const
 pdf_writer_wx::~pdf_writer_wx()
 {
     // This will finally generate the PDF file.
+  if(0 == std::uncaught_exceptions())
     pdf_dc_.EndDoc();
 }
--------->8-------->8-------->8-------->8-------->8-------->8-------->8-------



reply via email to

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