// g++ -O2 sum.cpp
#include <iostream>


// linear recursion
//  +-----+ +-----+ +-----+     +-----+ 
//  |     + |     + |     + ... |     + 
//  +-----+ +-----+ +-----+     +-----+
//  n function frames will be required, so will
//  run out of memory for some n
long long sum(long long n) {
    if ( n==1 ) return 1;

    // wasting some memory so that we run out of stack memory
    int waste[1<<12]; // dummy memory 
    for( int i=0;i<1<<12;++i) {
        waste[i]=i;
    }

    return n+sum( n-1 );
}



// tail recursion
void sum2_aux(long long n, long long & result) {
    if (n==0) return;

    // notice same useless block as before - so no cheating
    int waste[1<<12]; // dummy memory
    for( int i=0;i<1<<12;++i) {
        waste[i]=i;
    }

    sum2_aux( n-1, result+=n );
}

long long sum2(long long n) {
    long long result = 0;
    sum2_aux( n, result );
    return result;
}

int main()
{
    //sum(1000000); // crashes
    sum2(1000000); // works
}