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);
> }