C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Interest in constexpr std::shared_ptr?

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Fri, 29 Sep 2023 09:56:34 -0400
On Fri, Sep 29, 2023 at 8:28 AM Paul Keir via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Would anyone be interested in working on a proposal to add constexpr
> functionality to std::shared_ptr. An implementation based on libstdc++ is
> linked below:
>
> https://github.com/SCT4SP/constexpr_shared_ptr
>
> For convenience, `_GLIBCXX26_CONSTEXPR` and feature macro
> `__cpp_lib_constexpr_shared_ptr` have been defined and used throughout.
>
> The implementation takes advantage of recent support in GCC and Clang for
> P2738 (constexpr cast from void*: towards constexpr type-erasure). Beyond
> that we have the usual avoidance of placement new with
> `allocator_traits::construct` etc.; `std::is_constant_evaluated` allows
> avoidance of atomic operations; and `std::make_shared`,
> `std::allocate_shared` and variants have required two separate allocations
> to avoid illegal pointer casting.
>

I think adding `constexpr` throughout [util.smartptr.shared] sounds quite
plausible as a proposal for C++26/29 and would probably sail through LEWG.
However, your explanation makes me *personally* wary of the design, from an
implementor's point of view. You say implementors will have to use `if
consteval` to skip the atomic operations, because atomic isn't
constexpr-friendly. This means we'll have two different implementations to
test. (libc++ tried the "two different implementations" thing for
std::string, and is thankfully about to undo
<https://github.com/llvm/llvm-project/pull/66576> that decision.)
So perhaps a preliminary for "constexpr shared_ptr" would be "constexpr
atomic." Adding `constexpr` to [atomics.types.*] would be easy, we guess,
because atomic's only point is to be thread-safe, and at constexpr time we
have only one thread.
But wait — is it futureproof to assume that constexpr time will only *ever*
have one thread? If someone wanted constexpr std::thread or std::async
today, could we let them have it? If we prematurely assume that `atomic` or
`shared_ptr` can just *ignore* atomicness at constexpr time, are we
blocking off the avenue to constexpr `thread`?
(Constexpr `thread` also invites the spectre of constexpr race conditions,
which I guess would fall into the category of constexpr UB that the
compiler would be mandated to diagnose.)

I think a proposal should engage with this area in its "motivation"
sections. The reader should get a clear sense of whether the author's
stance is "This might be a problem for constexpr `thread`" or "This is not
a problem for constexpr `thread`" or "We do not ever want constexpr
`thread`" or what. There might even be prior literature on constexpr thread
and/or atomic; I don't know.

my $.02,
–Arthur

Received on 2023-09-29 13:56:47