[PATCH] libstdc++: Do not use 'not' alternative token in <format>

Jonathan Wakely jwakely@redhat.com
Wed Apr 16 11:17:11 GMT 2025


This fixes:
FAIL: 17_intro/headers/c++1998/operator_names.cc  -std=gnu++23 (test for excess errors)
FAIL: 17_intro/headers/c++1998/operator_names.cc  -std=gnu++26 (test for excess errors)

The purpose of 'not defined<format_kind<R>>' is to be ill-formed (as
required by [format.range.fmtkind]) and to give an error that includes
the string "not defined<format_kind<R>>". That was intended to tell you
that format_kind<R> is not defined, just like it says!

But user code can use -fno-operator-names so we can't use 'not' here,
and "! defined" in the diagnostic doesn't seem as user-friendly. It also
raises questions about whether it was intended to be the preprocessor
token 'defined' (it's not) or where 'defined' is defined (it's not).

Replace it with __no_primary_template<format_kind<R>> and a comment,
which seems almost as good. The diagnostic now looks like:

In file included from fmt.cc:1:
.../include/c++/15.0.1/format: In instantiation of 'constexpr const auto std::format_kind<int>':
fmt.cc:3:15:   required from here
    3 | auto i = std::format_kind<int>;
      |               ^~~~~~~~~~~~~~~~
.../include/c++/15.0.1/format:5164:31: error: use of 'std::format_kind<int>' before deduction of 'auto'
 5164 |       = __no_primary_template(format_kind<_Rg>); // must define specialization
      |                               ^~~~~~~~~~~~~~~~
.../include/c++/15.0.1/format:5164:30: error: '__no_primary_template' was not declared in this scope
 5164 |       = __no_primary_template(format_kind<_Rg>); // must define specialization
      |         ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~

libstdc++-v3/ChangeLog:

	* include/std/format (format_kind): Do not use 'not'
	alternative token to make the primary template ill-formed.
	Use __no_primary_template as the undefined identifier that will
	appear in diagnostics.
---

Testing now on x86_64-linux.

 libstdc++-v3/include/std/format | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index b1455977c65..9ce9b3cfed1 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -5160,7 +5160,8 @@ namespace __format
 
   /// @cond undocumented
   template<typename _Rg>
-    constexpr auto format_kind = not defined(format_kind<_Rg>);
+    constexpr auto format_kind
+      = __no_primary_template(format_kind<_Rg>); // must define specialization
 
   template<typename _Tp>
     consteval range_format
-- 
2.49.0



More information about the Libstdc++ mailing list