https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590
--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Richard Biener from comment #8) > So I've analyzed it more and it is because > > static _GLIBCXX17_CONSTEXPR size_t > length(const char_type* __s) > { > #if __cplusplus >= 201703L > if (__constant_string_p(__s)) > return __gnu_cxx::char_traits<char_type>::length(__s); > #endif > return __builtin_strlen(__s); > } > > confuses us because of the stupid structure of __constant_string_p. Ah, that is a difference between C++17 and C++14 that isn't just due to the explicit instantiations, I take it back! > Is this some odd requirement of O(1) length for constant strings? char_traits<C>::length is a constexpr function in C++17, so if called with a constant argument it must be evaluated at compile time. The rather ugly workaround with __builtin_constant_p was added because __builtin_strlen is not usable in constant expressions, see PR c++/80265. A proper fix would be very welcome. > Why not > make it constexpr evaluated instead? I'm not sure what you mean, but the problem is that __builtin_strlen doesn't work in constexpr functions (and wcslen isn't constexpr, and there's no __builtin_wcslen AFAIK). > Didn't we invent some special > __builtin_constant_p for this? __constexpr_p ()? Jakub implemented a __builtin_early_constant_p but I'm not sure if that's in trunk yet or if it's useful here. > Quoting > __constant_string_p: > > template<typename _CharT> > static _GLIBCXX_ALWAYS_INLINE constexpr bool > __constant_string_p(const _CharT* __s) > { > while (__builtin_constant_p(*__s) && *__s) > __s++; > return __builtin_constant_p(*__s); > }