https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87381

            Bug ID: 87381
           Summary: clang 6.0 will compile this constexpr construct, but
                    gcc 8.2.1 will not.
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eric-bugs at omnifarious dot org
  Target Milestone: ---

I'm trying to construct profile tags based on __PRETTY_FUNCTION__ at compile
time while making minimal use of preprocessor macros.  I've had a lot of
trouble with using integer arguments to constexpr functions, so that's why the
integers are templated. It occurs to me now that this may be because there were
implicit narrowing conversions involved, though the compiler didn't clearly
state this as the reason.

I'm going to try to make a new version of this that tries to be more careful
with how the integers are manipulated to see if it can be made simpler.

--------
#include <array>

constexpr int ce_strlen(char const *s)
{
    int i = 0;
    while (s[i]) ++i;
    return i;
}

template <int len>
constexpr auto as_array(char const *s)
{
    ::std::array<char, len + 1> output{};
    for (int i = 0; i < len; ++i) {
        output[i] = s[i];
    }
    output[output.size() - 1] = '\0';
    return output;
}

template <unsigned long s1, unsigned long s2>
constexpr auto paste_array(::std::array<char, s1> a, ::std::array<char, s2> b)
{
    constexpr unsigned long tlen = s1 + s2 - 1;
    ::std::array<char, tlen> output{};
    int o = 0;
    for (unsigned long i = 0; i < s1; ++i, ++o) {
        output[o] = a[i];
    }
    --o;
    for (unsigned long i = 0; i < s2; ++i, ++o) {
        output[o] = b[i];
    }
    return output;
}

#define stringify(x) #x
#define evstringify(x) stringify(x)

char const * joe()
{
    constexpr static auto mystr =
paste_array(paste_array(as_array<ce_strlen(__PRETTY_FUNCTION__)>(__PRETTY_FUNCTION__),
as_array<sizeof(" at line ") - 1>(" at line ")),
as_array<ce_strlen(evstringify(__LINE__))>(evstringify(__LINE__)));
    return mystr.data();
}

Reply via email to