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

Reply via email to