C++ Logo

std-proposals

Advanced search

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

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Thu, 15 Feb 2024 11:55:46 +0000
On Fri, 29 Sept 2023 at 14:56, Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> 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.
>

That wouldn't actually help anything in practice, because none of the Big
Three library implementations use std::atomic in std::shared_ptr.

A constexpr std::atomic would be implemented either by making the
underlying intrinsics (such as __atomic_fetch_add_n or
_InterlockedIncrement) usable in constant expressions, or (IMHO more
likely) by adding `if consteval` checks to the member functions of
std::atomic. The latter would not help the Big Three implementations to
ship a constexpr std::shared_ptr, since they don't use std::atomic anyway.
So they'd still need the `if consteval` checks in std::shared_ptr which is
what you're suggesting would be avoided by making std::atomic usable in
constexpr.

Received on 2024-02-15 11:57:02