https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108269
Bug ID: 108269 Summary: Incorrect __PRETTY_FUNCTION__ with std::array<char> in C++20 NTTP literal Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: camden.mannett at gmail dot com Target Milestone: --- Created attachment 54176 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54176&action=edit Source code When std::array<char, N> is used within a literal type that is used as an NTTP, it _looks_ like the __PRETTY_FUNCTION__ output always assumes that it is a null-terminated string which is then displayed without the last character - but it is not always a null! It is simplest to demonstrate with a compile-time string implementation (https://godbolt.org/z/8EnPfeWq7): #include <algorithm> #include <array> #include <iostream> namespace { template<typename T> class type_string_t { [[nodiscard]] constexpr static std::string_view generate() noexcept { constexpr auto sig = std::string_view{ static_cast<const char*>(__PRETTY_FUNCTION__) }; return sig; } public: constexpr static auto value = generate(); }; template<typename T> constexpr auto type_string = type_string_t<T>::value; template<std::size_t N> class str_storage { public: constexpr str_storage(const char (&str)[N]) { std::copy_n(&str[0], N, value.begin()); } constexpr str_storage(char c) : value{ c } { } std::array<char, N> value; }; str_storage(char) -> str_storage<1>; template<str_storage S> struct str {}; } int main() { std::cout << type_string<str<'a'>> << "\n" << type_string<str<"a">> << "\n" << type_string<str<"hello">> << std::endl; return 0; } This yields pretty much what you would expect when built via Clang (after removal of cruft): (anonymous namespace)::str<{{{97}}}> (anonymous namespace)::str<{{"a"}}> (anonymous namespace)::str<{{"hello"}}> However gcc does something different when the std::array contains only a single char: {anonymous}::str<{anonymous}::str_storage<1>{std::array<char, 1>{""}}> {anonymous}::str<{anonymous}::str_storage<2>{std::array<char, 2>{"a"}}> {anonymous}::str<{anonymous}::str_storage<6>{std::array<char, 6>{"hello"}}> It seems to always represent the char array as a null-terminated string literal, which isn't always true.