https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87381
--- Comment #4 from eric-bugs at omnifarious dot org --- Given the new way of looking at things prompted by the correction of my erroneous idea, I've rethought how to simplify this, and the simplification does work in gcc 8.2, and I think is generally more correct: ---------- #include <array> #include <cstddef> using ary_size_t = ::std::array<char, ::std::numeric_limits<int>::max()>::size_type; template <::std::size_t len> constexpr auto as_stdarray(const char (&s)[len]) { ::std::array<char, len> output{}; for (::std::size_t i = 0; i < len; ++i) { output[i] = s[i]; } return output; } template <ary_size_t s1, ary_size_t s2, ary_size_t... sn> constexpr auto paste_array(::std::array<char, s1> a, ::std::array<char, s2> b, ::std::array<char, sn>... remaining) { constexpr auto numarys = 1 + sizeof...(remaining); constexpr ary_size_t tlen = ((s1 + s2) + ... + sn) - numarys; ::std::array<char, tlen> output{}; int o = 0; auto copy_into = [&o, &output](auto const &a) { for (ary_size_t i = 0; i < a.size(); ++i, ++o) { output[o] = a[i]; } --o; }; copy_into(a); (copy_into(b) , ... , copy_into(remaining)); return output; } #define stringify(x) #x #define evstringify(x) stringify(x) char const * joe() { constexpr static auto mystr = paste_array(as_stdarray(__FUNCTION__), as_stdarray(" at line "), as_stdarray(evstringify(__LINE__))); return mystr.data(); } ---------- Godbolt link: https://godbolt.org/z/jMJ94L Because ::std::array doesn't trivially decay into a pointer, I find it easier to work with in a sensible way, which is why I convert everything to an std::array first. I should probably rename paste_array to concat_zstrings.