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