On Mon, Jul 14, 2025 at 10:43 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> This makes it possible to use `new(std::nothrow) X` without linking to > libsupc++ or libstdc++. > > To ensure we still export the symbol from the library we need to > suppress the inline variable in libsupc++/new_handler.cc which is done > by defining a macro. > > libstdc++-v3/ChangeLog: > > * libsupc++/new (nothrow): Define as inline variable. > * libsupc++/new_handler.cc (_GLIBCXX_DEFINE_NOTHROW_OBJ): > Define. > --- > > Tested powerpc64le-linux. > > libstdc++-v3/libsupc++/new | 4 ++++ > libstdc++-v3/libsupc++/new_handler.cc | 2 ++ > 2 files changed, 6 insertions(+) > > diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new > index fb36dae25a6d..85d28ff40769 100644 > --- a/libstdc++-v3/libsupc++/new > +++ b/libstdc++-v3/libsupc++/new > @@ -125,7 +125,11 @@ namespace std > #endif > }; > > +#if defined __cpp_inline_variables && ! defined > _GLIBCXX_DEFINE_NOTHROW_OBJ > + inline constexpr nothrow_t nothrow{}; > +#else > extern const nothrow_t nothrow; > +#endif > If you move variable definition before include, this would become: +#ifndef _GLIBCXX_DEFINE_NOTHROW_OBJ +# ifdef __cpp_inline_variables + inline constexpr nothrow_t nothrow{}; + # else extern const nothrow_t nothrow; +# endif +#endif GCC and clang also accepts, i.e. version when we always have extern declaration: +#if defined __cpp_inline_variables && ! defined _GLIBCXX_DEFINE_NOTHROW_OBJ + inline constexpr nothrow_t nothrow{}; +#endif extern const nothrow_t nothrow; > /** If you write your own error handler to be called by @c new, it must > * be of this type. */ > diff --git a/libstdc++-v3/libsupc++/new_handler.cc > b/libstdc++-v3/libsupc++/new_handler.cc > index 7cd3e5a69fde..96dfb796c64a 100644 > --- a/libstdc++-v3/libsupc++/new_handler.cc > +++ b/libstdc++-v3/libsupc++/new_handler.cc > @@ -23,6 +23,8 @@ > // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > // <http://www.gnu.org/licenses/>. > > +#define _GLIBCXX_DEFINE_NOTHROW_OBJ 1 > Could we also move the definition of nothrow here (before including new), so entities in header new always see it's definition when it is constexpr? I do not think there is any (even bening) ODR violation possibility here, but we can avoid the risk that way., > + > #include "new" > #include <bits/atomic_lockfree_defines.h> > In the bit of code that is not visible here, there is variable definition: > const std::nothrow_t std::nothrow = std::nothrow_t{ }; This mean for some TU's the variable is declared constexpr (if __cpp_inline_variables is set), but for others not (implicit constexpr for some variables apply only for integral types). Could we change it to: #ifdef __cpp_inline_variables // purposely match when header defines it as inline/constexpr constexpr #endif const nothrow_t nothrow; > -- > 2.50.1 > >