C++ Logo

sg12

Advanced search

Re: [ub] memcpy blessing a new object of statically unknown type

From: David Krauss <david_work_at_[hidden]>
Date: Sun, 10 Jan 2016 12:32:08 +0800
> On 2016–01–10, at 5:42 AM, Gabriel Dos Reis <gdr_at_[hidden]> wrote:
>
> My assumption has always been that std::launder is a zero-overhead abstraction (really a no-op at the machine level) whole sole purpose is to inform the static semantics elaborator about the lifetime and type of a given storage. I hope we aren’t considering anything more complicated than that.

This perfectly expresses my expectation as well. But now it looks slightly different: The type remains malleable, and rather than marking an area of storage, launder provides a single blessed reference to an unbounded region. (If reinterpret_cast and downcasts are valid on the result of launder, what’s its connection to the type system? Why can’t it operate on void*?)

And, it’s not exactly zero-overhead, as its purpose is to disable an optimization which might be harmless. For example, take N4303 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4303.html>’s motivating case in std::optional. Statically, optional’s contained object might have been created by placement-new, so the accessors always need to launder their return value. This would seem to make optional slower than “native” objects.

namespace std {
template< typename t >
t & optional< t >::operator * ()
    { return * launder( & this->storage.object ); }
}

void foo() {
    int i;
    std::optional< int > o = 3;

    i = *o; // Must load *o from memory because address was laundered.
    i = *o + *o; // Reload twice more. Will optimizers second-guess launder?
}

Likewise, MSVC appears to be remembering the value inside my wrapper’s NSDM embedded storage. It’s a beneficial optimization to the common case of a sequence of accesses, so it would be nice not to lose it.

It would also be easier-to-use if the assignment operator could inform the compiler when a lifetime begins, as opposed to the accessors providing notification that a new lifetime might have already begun. But, I suppose that’s not feasible, or we wouldn’t need launder in the first place.


Received on 2016-01-10 05:32:22