lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Reference lifetime extension


From: Greg Chicares
Subject: Re: [lmi] Reference lifetime extension
Date: Thu, 11 Oct 2018 23:29:12 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On 10/11/18 8:55 PM, Vadim Zeitlin wrote:
> On Thu, 11 Oct 2018 20:31:12 +0000 Greg Chicares <address@hidden> wrote:
> 
> GC> I had saved this little change off to the side, and was thinking of
> GC> committing it, but luckily it faulted when I tested it repeatedly:
> GC>   Unhandled exception: page fault on execute access to 0x068a9050 in 
> 32-bit code (0x068a9050).
> GC> so I know it's wrong; but why, exactly?
> GC> 
> GC> 
> ---------8<--------8<--------8<--------8<--------8<--------8<--------8<-------
> GC> diff --git a/ledger_pdf.cpp b/ledger_pdf.cpp
> GC> index d3eb99c4..c83a0d3b 100644
> GC> --- a/ledger_pdf.cpp
> GC> +++ b/ledger_pdf.cpp
> GC> @@ -94,6 +94,6 @@ std::string write_ledger_as_pdf(Ledger const& ledger, 
> fs::path const& filepath)
> GC>      if(0 == scaled_ledger.GetLedgerInvariant().ScalePower())
> GC>      scaled_ledger.AutoScale();
> GC> -    auto const pdf = ledger_pdf_generator::create();
> GC> -    pdf->write(scaled_ledger, pdf_out_file);
> GC> +    ledger_pdf_generator const& pdf = *ledger_pdf_generator::create();
> GC> +    pdf.write(scaled_ledger, pdf_out_file);
> GC>  
> GC>      return pdf_out_file.string();
> GC> 
> --------->8-------->8-------->8-------->8-------->8-------->8-------->8-------
> 
>  Sorry if this is a trick question, but this seems relatively obvious to
> me: the shared_ptr<> returned by ledger_pdf_generator::create() is
> destroyed at the end of the statement, as there is no const reference bound
> to it that could possibly extend its life-time. Instead, you have a const
> reference set to the result of its operator*(),

So far, all of this is clear to me; but...

> but this operator doesn't
> return a temporary object, so rules about extending its life-time don't
> apply at all.

It doesn't return a temporary?

A temporary would be created [class.temporary/1.1]
| when a prvalue is materialized so that it can be used as a glvalue
and
| Temporary objects are materialized:
| (2.1) — when binding a reference to a prvalue

I believe this line does bind a reference to something:
  ledger_pdf_generator const& pdf = *ledger_pdf_generator::create();
and therefore that "something", i.e. what shared_ptr::operator*()
returns, must not be a prvalue...right? What then is its "value
category" [basic.lval/1]?

I was hoping I'd never have to learn this stuff.

>  Avoiding using shared_ptr<> without real reason is a good idea, of course,
> but as long as you do use it, you must not use the pointer (or reference,
> which is the same thing) it contains directly, this is really error-prone
> and is only ever necessary when interfacing with legacy code.

I've found a way to avoid it in this case, which I'll push presently.



reply via email to

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