2

I have this piece of code:

template <int N>
struct flag {
    friend constexpr int adl_flag(flag<N>); //function prototype
};

template <int N>
struct writer {
    // Template instantiation "implements" adl_flag function.
    friend constexpr int adl_flag(flag<N>) { return N; }

    // Accessing this constant forces this struct to be instantiated.
    static constexpr int value = N; 
};

template <int N, int M = adl_flag(flag<N>{})>
int constexpr reader(int, flag<N>, int R = reader(0, flag<N + 1>{}))
{
    // When adl_flag(flag<N>) has already been implemented, overload resolution prefers this one and 
    // in turn the default parameter triggers adl_flag(flag<N+1>) to be called
    return R;
}

template <int N>
int constexpr reader(float, flag<N>)
{
    // When adl_flag(flag<N>) has not been implemented yet, the overload above results in substitution failure and this one is chosen, and the recursion stops. 
    //This function thus returns the lowest N that adl_flag(flag<N>) has not been implemented yet. 
    return N;
}

template <int N = 0,int R = reader<N>(0, flag<N>{})>
int constexpr next(int next=writer<R>::value)
{
    //This function queries the next N that adl_flag(flag<N>) is not implemented, and then implements it. 
    //These all happens in the evaluation of default parameters, which is guaranteed to be executed every time this function is called with default parameters.
    return next;
}
int main()
{
    static_assert(next()==0,"Wrong result");
    static_assert(next()==1,"Wrong result");
    static_assert(next()==2,"Wrong result");
    static_assert(next()==3,"Wrong result");
}

This basically implements "constexpr counter". This worked great and the static_assert's passed with compile options "-std=gnu++11"...until g++ 8.1.

Since g++ 8.1, this code no longer works. Instead, it seems that

    static_assert(next()==0,"Wrong result");
    static_assert(next()==1,"Wrong result");
    static_assert(next()==1,"Wrong result");
    static_assert(next()==1,"Wrong result");

this passes the compilation.

Can anyone explain what happened to g++ compiler? Is it a bugfix in g++ 8.1? or is it a bug that is introduced in g++ 8.1?

eivour
  • 1,678
  • 12
  • 20

0 Answers0