C++ Logo

std-discussion

Advanced search

Re: CWG 2256 resolution breaks reasonable code

From: Christopher Hallock <christopherhallock_at_[hidden]>
Date: Sat, 8 Feb 2020 11:29:42 -0500
On Fri, Feb 7, 2020 at 4:11 PM Tam S. B. <cpplearner_at_[hidden]> wrote:

> AFAIK it's fine to use the value of private_constant even outside its
> lifetime (or at least that's the intent). See [conv.lval]/2.
>
> Though if private_constant is passed by reference (and accessed through
> the reference), then [conv.lval]/2 is no help.
>

Ah, thanks for the correction! That significantly reduces the scope of the
problem. But how can a function like the following be fixed?

// Contract:
// - returns ref to a single POD object (address-stable)
// - can be called during std::exit() without UB
// - the object can be read during std::exit() without UB
// - thread-safety is a bonus but not required
const info& get_info()
{
    static const info i = /*...*/; // oops!
    return i;
}

Depending on destruction order, the static local i can be destroyed before
the last time it is read and/or before the last time get_info() is called.
Either case triggers UB. I literally do not know how to fix this function's
implementation without also changing its contract and without resorting to
non-portable techniques! ("Construct with new" you might say, but then
where are you going to stash the pointer? "Easy, a static local... oh")

The issue resolution appears to take away a tool in our toolbox: storage at
a statically-known location that lasts until termination.

Received on 2020-02-08 10:32:39