On Tue, 3 Dec 2024 at 16:19, Giuseppe D'Angelo
<giuseppe.dang...@kdab.com> wrote:
>
> Hello,
>
> The attached patch changes std::weak_ptr "converting move
> constructor/assignment" -- that is, from a rvalue weak_ptr<Derived> to a
> weak_ptr<Base>.
>
> In the general case, such conversion requires lock()ing the weak_ptr
> because the pointed-to object might have already been destroyed, and a
> Derived->Base pointer conversion requires dereferencing the pointer iff
> Base is a virtual base class of Derived. Therefore the correct thing to
> do in the general case is to lock() the weak_ptr, call get() on the
> resulting shared_ptr, and do the pointer conversion while this
> shared_ptr is alive.
>
> However, the newly added __is_virtual_base_of builtin allows us to
> micro-optimize this pointer upcast, and avoid calling lock() (and paying
> for the associated atomic operations) in case Base is *not* a virtual
> base class of Derived. In this case we can "just" perform the upcast;
> as far as I know, no ABI requires dereferencing the pointer in the
> non-virtual inheritance case.

This is a nice optimization!

We would usually use _S_safe_upcast for the name of a static member
function, although I think __safe_upcast is OK here.

Do we need the _Compatible constraint on __safe_upcast? It's only
called internally from code that has already enforced that constraint,
so checking again just slows compilation down.

I've been moving from using `if _GLIBCXX17_CONSTEXPR` to just
surrounding the function in diagnostic pragmas so that we can use `if
constexpr` unconditionally, i.e.

#pragma GCC diagnostic push
#pragma GCC diagnostic pushignored "-Wc++17-extensions" // if constexpr
...
#pragma GCC diagnostic pop

That way we get the benefits of `if constexpr` even in C++11 mode.

We still have lots of code using _GLIBCXX17_CONSTEXPR but I think we
should phase it out in favour of using `if constexpr` unconditionally
(or at least using `if _GLIBCXX_CONSTEXPR` for code which needs to
compile as C++98 too).

Reply via email to