https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99181
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- static _GLIBCXX_CONSTEXPR bool lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { // LWG 467. return (static_cast<unsigned char>(__c1) < static_cast<unsigned char>(__c2)); } static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return 0; #if __cplusplus >= 201703L if (__builtin_constant_p(__n) && __constant_char_array_p(__s1, __n) && __constant_char_array_p(__s2, __n)) return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); #endif return __builtin_memcmp(__s1, __s2, __n); } Seems the std::char_traits<char>::lt specialization implements LWG467, and so does std::char_traits<char>::compare when not in constant expression evaluation, but the C++17 case above will call __gnu_cxx::char_traits<char_type>::compare which doesn't know about LWG 467. --- libstdc++-v3/include/bits/char_traits.h.jj 2021-01-04 10:26:03.558953845 +0100 +++ libstdc++-v3/include/bits/char_traits.h 2021-02-22 10:42:08.197199781 +0100 @@ -349,7 +349,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__builtin_constant_p(__n) && __constant_char_array_p(__s1, __n) && __constant_char_array_p(__s2, __n)) - return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } #endif return __builtin_memcmp(__s1, __s2, __n); } seems to fix this, but not sure if there isn't a better way.