C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relocation in C++

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Wed, 2 Mar 2022 08:05:47 -0500
On Tue, Mar 1, 2022 at 5:26 PM Andreas Ringlstetter via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> > The larger picture here seems to be an effort to make move semantics
> friendlier and easier to use. I began an informal survey on open-std of
> papers on move semantics.
>
> Move semantics so far suffer in 2 domains:
> - There is no way in the language standard to notify the compiler that
> an object is trivially deconstrutible as it hasn't been touched after
> a specific class of constructor
> - There is no way to tell the compiler that an object which has just
> been moved shall be implicitly assumed to have returned to such a
> pristine state.
>
[...]

> Is this limited to move constructors? No, a quick thought experiment
> shows this is actually universally applicable:
>
> struct unique_ptr {
> unique_ptr() noexcept [[post=trivial]] { /* non-trivial constructor
> */};
> unique_ptr(unique_ptr&& [[post=trivial]] other);
> ~unique_ptr() [[post=trivial]] { /* non-trivial destructor */};
> void reset() [[post=trivial]];
>

Andreas: This is a philosophically interesting idea. However, it suffers
from the same general problem as Niall's [[move_relocates]] except worse.
The problem is that it enables a lot of satisfying *bookkeeping*, but
doesn't actually enable the *practical optimizations* that we care about
w.r.t. trivial relocation. Here are some examples:

(1) When we reallocate a std::vector<T>, can we just memcpy the bytes from
the old buffer into the new buffer? or must we tediously call some
user-defined operation on T in a loop? Marking your move-ctor
[[post=trivial]] tells me that once I've tediously called the move-ctor in
a loop, I can skip calling the *destructor* in a loop; but it still doesn't
tell me that I can memcpy in the first place.

(2) When we put a T into a std::any, can its "relocate" affordance use a
common memcpying codepath? or must we generate a "relocate" lambda that
type-erases the move-ctor and dtor of this specific T? Marking your
move-ctor [[post=trivial]] doesn't tell me that your relocation operation
is tantamount to memcpy; it doesn't actually tell me *anything* about the
behavior of your relocation operation. I still have to generate a lambda to
type-erase it; I can't use a common codepath.

(3) When we swap two objects of type T, can we just swap their bytes? or
must we call some user-defined operation(s) on T? This affects
std::rotate, std::partition, std::sort, and many other STL algorithms.

https://quuxplusone.github.io/blog/tags/#relocatability

–Arthur

Received on 2022-03-02 13:05:59