On Fri, Feb 7, 2020 at 4:11 PM Tam S. B. <cpplearner@outlook.com> 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.