C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Making contiguous objects

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 12 Mar 2023 14:43:23 -0400
On Sun, Mar 12, 2023 at 1:59 PM Breno GuimarĂ£es <brenorg_at_[hidden]> wrote:

> >And now I'm confused: Is this make_contiguous_*objects* or
> make_contiguous_*storage*? Because most library users will need the
> latter, not the former.
>
> It's "_objects". I don't agree most library users would need the latter.
> At least it's not in the use cases I looked at.
>

You give the following use-cases in the paper:

https://github.com/llvm/llvm-project/blob/2f887c9a760dfdffa584ce84361912fe122ad79f/libcxx/include/__memory/shared_ptr.h#L1139
(btw, you call this "the LLVM implementation," but it would be clearer to
say "the libc++ implementation of make_shared")
requires allocation without construction (it needs to pass Args... to the
ctor).

https://github.com/abseil/abseil-cpp/blob/d8933b836b1e1aac982b1dd42cc6ac1343a878d5/absl/container/internal/raw_hash_set.h#L1342
performs allocation without construction, although it probably doesn't care
(its types being constructed are trivial).

https://github.com/mattreecebentley/plf_hive/blob/8c2bf6d9606df1d76900751ffffc472e994b529b/plf_hive.h#L174
requires allocation without construction (it doesn't want to construct `T`
objects yet), although the current implementation wraps `T` in a union both
for this reason and for other reasons, so
default-constructing-the-union-type ends up doing the same thing as
not-constructing, in the end.


> Some might want to defer the initialization of some arrays, but then they
> use it like `std::make_contiguous_objects<Metadata,
> ElementAlignedStorage>(nElements, nElements)`
> And manually do part of the work.
> But make_contiguous objects would give the buffer size calculation
> (including alignment) and the exception-safe creation of the metadata array.
>

Right, that's why the storage-allocating version is still a value-add over
"nothing at all." It does the buffer size calculation, including alignment,
and hands back the component-array pointers to the caller. (Ville, this
answers your question about "why is this better than just using the
allocator directly.")

But I don't see any use-cases yet where we want the T objects to be
default-constructed. Default-constructing the T objects is *explicitly
impossible *in some cases and *harmless but unnecessarily slow* in others.
We haven't yet seen a case where it's helpful. That doesn't mean you can't
provide an additional entrypoint that does construct the Ts; it just means
that we haven't yet seen a positive use-case for that entrypoint. All our
use-cases so far are use-cases for the allocating-but-not-constructing
entrypoint.

–Arthur

Received on 2023-03-12 18:43:37