Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile time recursion and conditionals

I was reading the responses to "Printing 1 to 1000 without loop or conditionals" and I am wondering why it is necessary to have the special case for NumberGeneration<1> in the top answer.

If I remove that and add a check for N == 1 in the template (code below), the code fails compilation with "template instantiation depth exceeds maximum" but I'm not sure why. Are conditionals handled differently in compile-time?

#include <iostream>

template<int N>
struct NumberGeneration
{
    static void out(std::ostream& os)
    {
        if (N == 1)
        {
            os << 1 << std::endl;
        }
        else
        {
            NumberGeneration<N-1>::out(os);
            os << N << std::endl;
        }
    }
};

int main()
{
    NumberGeneration<1000>::out(std::cout);
}
like image 717
baris.m Avatar asked Jan 06 '12 15:01

baris.m


3 Answers

Code generation and compilation doesn't branch depending on conditionals! Consider this:

// don't declare bar()!

void foo()
{
     if (false) { bar(); }
}

If you never declare bar(), this is a compilation error even though the inner scope can never be reached. For the same reason, NumberGeneration<N-1> is always instantiated, no matter whether that branch can be reached or not, and you have infinite recursion.

Indeed, the static analogue of conditionals is precisely template specialization:

template <> struct NumberGeneration<0> { /* no more recursion here */ };
like image 108
Kerrek SB Avatar answered Oct 22 '22 21:10

Kerrek SB


The conditional if will not be handled at compile time. It will be handled at runtime.

Thus, even for N=1, the compiler will generate NumberGenerator<0>, then NumberGenerator<-1> ... endlessly, until reaching template instantiation depth.

like image 29
Didier Trosset Avatar answered Oct 22 '22 20:10

Didier Trosset


Templates are instantiated at compile time, the template special case prevents the compiler from recursing below 1 when compiling.

if-clauses are evaluated at runtime, so the compiler has already failed at compiling your code when it would have any effect.

like image 30
Joachim Isaksson Avatar answered Oct 22 '22 22:10

Joachim Isaksson