// PR c++/69261 // { dg-do run { target c++14 } } typedef __SIZE_TYPE__ size_t; template struct S { constexpr S() = default; template constexpr S (char const (&d)[M]) : data { 0 } { static_assert (M <= N, "size!"); for (size_t i = 0; i != M; i++) data[i] = d[i]; } char data[N]; }; template constexpr S s (char const (&d)[N]) { S c {}; for (size_t i = 0; i != N; i++) c.data[i] = d[i]; return c; } template constexpr auto concat (S const& s1, S const& s2) { S s (s1.data); for (size_t i = 0; i != M; i++) s.data[N + i - 1] = s2.data[i]; return s; } template constexpr auto concat (char const (&x)[N], char const (&y)[M]) { S tmp { x }; for (size_t i = 0; i != M; i++) tmp.data[N+i-1] = y[i]; return tmp; } int main () { auto constexpr s1 = s ("bla"); auto constexpr s2 = s ("blub"); S<8> constexpr s1s2 = concat (s1, s2); auto constexpr c = concat ("bla", "blub"); if (__builtin_strcmp (s1.data, "bla") || __builtin_strcmp (s2.data, "blub") || __builtin_strcmp (s1s2.data, "blablub") || __builtin_strcmp (c.data, "blablub")) __builtin_abort (); }