[PATCH] libstdc++: replace assert with __glibcxx_assert (PR libstdc++/125228)

Dragon Archer dragon-archer@outlook.com
Fri May 8 18:16:15 GMT 2026


PR libstdc++/125228

This patch replaces the uses of `assert` in ryu and debug.cc with
`__glibcxx_assert`, and removed their direct dependency on `<cassert>`.
To avoid modifying the third-party ryu headers, this patch use
`#pragma push_macro` / `#pragma pop_macro` to locally
redefine `assert` to `__glibcxx_assert` when including the ryu headers.

libstdc++-v3/ChangeLog:

	PR libstdc++/125228
	* src/c++11/debug.cc: Replace assert with __glibcxx_assert,
	and remove the include of <cassert>.
	* src/c++17/floating_to_chars.cc: Likewise, but redefine
	assert as __glibcxx_assert using pragma push/pop_macro.

--

From 76f866652f9a7e2fc4faf012f6b356e9a85ecb8d Mon Sep 17 00:00:00 2001
From: dragon-archer <dragon-archer@outlook.com>
Date: Fri, 8 May 2026 19:14:49 +0800
Subject: [PATCH] libstdc++: Use __glibcxx_assert instead of assert

Unlike `__glibcxx_assert` which is guarded
by `_GLIBCXX_ASSERTIONS` and enabled only in Debug
build of libstdc++, `assert` is either always enabled, or
always disabled if manually defining `NDEBUG` before
`#include <cassert>` or `#include <assert.h>`. This not
only makes `assert` inflexible, but also introduces extra
runtime overhead and/or increased binary size in Release
builds.

Uses of `assert` without `NDEBUG` introduces `__FILE__`
into the final library, and can be easily found using
`string`

This is a long standing issue, dating from at least GCC
8.5.0 to latest GCC 16.1.0
---
 libstdc++-v3/src/c++11/debug.cc             | 33 ++++++++++-----------
 libstdc++-v3/src/c++17/floating_to_chars.cc |  5 +++-
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 7049d5f1238..9a36bdfabb9 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -33,7 +33,6 @@
 #include <debug/safe_local_iterator.h>
 #include <debug/vector>
 
-#include <cassert>
 #include <cstdio>	// for std::fprintf, stderr
 #include <cstdlib>	// for std::abort
 #include <cctype>	// for std::isspace.
@@ -888,7 +887,7 @@ namespace
   void
   print_named_name(PrintContext& ctx, const _Parameter::_Named& named)
   {
-    assert(named._M_name);
+    __glibcxx_assert(named._M_name);
     pretty_print(ctx, named._M_name, print_word);
   }
 
@@ -985,7 +984,7 @@ namespace
 	print_iterator_state(ctx, iterator);
       else if (__builtin_strcmp(fname, "sequence") == 0)
 	{
-	  assert(iterator._M_sequence);
+	  __glibcxx_assert(iterator._M_sequence);
 	  print_address(ctx, iterator._M_sequence);
 	}
       else if (__builtin_strcmp(fname, "seq_type") == 0)
@@ -999,43 +998,43 @@ namespace
   void
   print_field(PrintContext& ctx, const _Parameter& param, const char* fname)
   {
-    assert(param._M_kind != _Parameter::__unused_param);
+    __glibcxx_assert(param._M_kind != _Parameter::__unused_param);
 
     const auto& variant = param._M_variant;
     switch (param._M_kind)
     {
     case _Parameter::__iterator:
       if (!print_iterator_field(ctx, fname, variant._M_iterator))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     case _Parameter::__sequence:
       if (!print_instance_field(ctx, fname, variant._M_sequence))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     case _Parameter::__integer:
       if (!print_named_field(ctx, fname, variant._M_integer))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     case _Parameter::__string:
       if (!print_named_field(ctx, fname, variant._M_string))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     case _Parameter::__instance:
       if (!print_instance_field(ctx, fname, variant._M_instance))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     case _Parameter::__iterator_value_type:
       if (!print_type_field(ctx, fname, variant._M_iterator_value_type))
-	assert(false);
+	__glibcxx_assert(false);
       break;
 
     default:
-      assert(false);
+      __glibcxx_assert(false);
       break;
     }
   }
@@ -1198,9 +1197,9 @@ namespace
 	  }
 
 	// Get the parameter number
-	assert(*str >= '1' && *str <= '9');
+	__glibcxx_assert(*str >= '1' && *str <= '9');
 	size_t param_index = *str - '0' - 1;
-	assert(param_index < num_parameters);
+	__glibcxx_assert(param_index < num_parameters);
 	const auto& param = parameters[param_index];
 
 	// '.' separates the parameter number from the field
@@ -1208,7 +1207,7 @@ namespace
 	++str;
 	if (*str != '.')
 	  {
-	    assert(*str == ';');
+	    __glibcxx_assert(*str == ';');
 	    ++str;
 	    if (param._M_kind == _Parameter::__integer)
 	      print_integer(ctx, param._M_variant._M_integer._M_value);
@@ -1226,8 +1225,8 @@ namespace
 	++str;
 	while (*str != ';')
 	  {
-	    assert(*str);
-	    assert(field_idx < max_field_len - 1);
+	    __glibcxx_assert(*str);
+	    __glibcxx_assert(field_idx < max_field_len - 1);
 	    field[field_idx++] = *str++;
 	  }
 	++str;
@@ -1382,7 +1381,7 @@ namespace __gnu_debug
     print_literal(ctx, "Error: ");
 
     // Print the error message
-    assert(_M_text);
+    __glibcxx_assert(_M_text);
     print_string(ctx, _M_text, -1, _M_parameters, _M_num_parameters);
     print_literal(ctx, ".\n");
 
diff --git a/libstdc++-v3/src/c++17/floating_to_chars.cc b/libstdc++-v3/src/c++17/floating_to_chars.cc
index 9bddffd70ff..264e520e187 100644
--- a/libstdc++-v3/src/c++17/floating_to_chars.cc
+++ b/libstdc++-v3/src/c++17/floating_to_chars.cc
@@ -26,7 +26,6 @@
 
 #include <bit>
 #include <cfenv>
-#include <cassert>
 #include <cmath>
 #include <cstdio>
 #include <cstring>
@@ -106,6 +105,9 @@ namespace
 
   namespace ryu
   {
+#pragma push_macro("assert")
+#undef assert
+#define assert __glibcxx_assert
 #include "ryu/common.h"
 #include "ryu/digit_table.h"
 #include "ryu/d2s_intrinsics.h"
@@ -123,6 +125,7 @@ namespace
 # include "ryu/ryu_generic_128.h"
 # include "ryu/generic_128.c"
     } // namespace generic128
+#pragma pop_macro("assert")
 
     using generic128::floating_decimal_128;
     using generic128::generic_binary_to_decimal;
-- 
2.54.0.windows.1



More information about the Libstdc++ mailing list