Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compiler tries to evaluate unreachable code after constexpr if

I've experimenting with C++17 lately and found this:

template<size_t i>
void recurse()
{
    if constexpr(i == 0)
        return;
    return recurse<i - 1>();
}

Trying to call recurse<4>(); will lead to

fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) return recurse<i - 1>();

Adding an else fixes the error:

template<size_t i>
void recurse()
{
    if constexpr(i == 0)
        return;
    else
        return recurse<i - 1>();
}

Is this a bug? Unfortunately I don't have access to another compiler than gcc 7.3.0 right now.

like image 473
HenrikS Avatar asked Jul 18 '18 09:07

HenrikS


1 Answers

No: isn't a bug.

Both if constexpr and else are necessary.

In you first version

template<size_t i>
void recurse()
{
    if constexpr(i == 0)
        return;
    return recurse<i - 1>();
}

the recurse<i-1>() is compiled also when i == 0, so is generated recurse<-1>(), so is generated recurse<-2>(), etc.

You need the else to link the return recurse<i-1>() to if constexpr (i == 0) and avoid it's compilation when i == 0 ending the recursion.

You can try the second version removing constexpr

template<size_t i>
void recurse()
{
    if (i == 0)
        return;
    else
        return recurse<i - 1>();
}

and you should get the same "template instantiation depth exceeds maximum of 900" recursion error.

like image 75
max66 Avatar answered Sep 20 '22 12:09

max66