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

Reply via email to