lmi
[Top][All Lists]
Advanced

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

Re: [lmi] [lmi-commits] master 8cccd20 5/9: Note a mystery


From: Greg Chicares
Subject: Re: [lmi] [lmi-commits] master 8cccd20 5/9: Note a mystery
Date: Sat, 22 Sep 2018 23:21:47 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

On 2018-09-19 15:30, Vadim Zeitlin wrote:
> On Wed, 19 Sep 2018 09:19:33 -0400 (EDT) Greg Chicares <address@hidden> wrote:
> 
> GC>     Note a mystery

    // PDF !! Apparently this is some sort of quasi-global object?
    html_cell_for_pdf_output::pdf_context_setter the_pdf_context

> GC>     It seems that this nowhere-referenced object must exist.
> 
>  Just in case you haven't found it yet, the mystery is explained in the
> comments before pdf_context_setter and pdf_context itself. I hope the
> explanations there are sufficiently clear to answer any questions about why
> this object must exist, but please let me know if it doesn't.

Okay, I've reread that again, and now, with more knowledge of this
TU gained over the last few days, maybe I understand. I had read this:

    // This is ugly, but we have to use a global variable to make pdf_writer_wx
    // and wxDC objects used by the main code accessible to this cell class,

and interpreted "global" as meaning "at namespace scope", so I
expected some almost-a-singleton, more or less like this variable:

volatile bool ensure_setup = ledger_pdf_generator::set_creator
    (ledger_pdf_generator_wx::do_create
    );

But now I see that it's like those /wx[A-Z][A-Za-z]*er/ classes
  wxDCFontChanger
  wxDCTextColorChanger
  wxDCClipper
so this "global variable" is actually just a variable whose lifetime
begins before, and ends after, any object that uses the pdf_context
that this pdf_context_setter establishes.

But...wait, is that right? There are actually two variables of interest:

(1) the context itself--a static data member, originally:

    html_cell_for_pdf_output::pdf_context
    html_cell_for_pdf_output::pdf_context_for_html_output;

which I rewrote thus:

    static inline pdf_context pdf_context_for_html_output = {};

supposing that you would have written it 'inline' if the original had
been written for C++17 or later.

(2) the context setter--a class instance, at function scope in
pdf_illustration::render_all() :

    html_cell_for_pdf_output::pdf_context_setter the_pdf_context

Now, (1) is the "global variable"--more precisely, a static data member.
Its lifetime is, in practical terms, eternal. It's a unique object,
which has the same address as long as the program is running.

And (2) is not "global" in any sense: it's an RAII thing, a local object
that lives on the stack while render_all() is running. It's a different
object for each different invocation of render_all(), defined in the
scope of that function, which determines its lifetime.

And, because (1) is eternal, its pointers would have to be dangling
when render_all() isn't on the call stack, except that (2) has a dtor
that resets the (1) pointers to nullptr.

So now I return to my inline comment:

        // PDF !! Apparently this is some sort of quasi-global object?
        html_cell_for_pdf_output::pdf_context_setter the_pdf_context

and believe my misunderstanding was taking the word "global" as intended
to characterize (2), whereas that word applies to (1). And you must mean
"global" in a general sense of "universally available throughout the TU",
and not in the narrow sense of C++17 (N4659) 6.3.6p3:
  "A name with global namespace scope is said to be a global name."
which couldn't apply here anyway because the entire TU is in an unnamed
namespace (except for the linking macro).



reply via email to

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