The function can actually cause an stack overflow (each level of recursion will consume a bit of the stack until it get's all consumed).
As others have mentioned, you can convert the recursive function into a loop, which in this case would be simple, or you can modify the recursion to allow for tail-call optimization (have the compiler transform the recursion into a loop).
Just for the sake of it, to transform into a tail recursive call, the last statement of the function must be a return with the result obtained from the recursive call. Your code cannot be optimized away because your return statement contains m*factorial(n-1)
, that is, you don't return the value of the recursion, but actually operate on it before returning.
The transformation to make it tail recursive require pushing the multiplication down to the recursive call, and that is usually performed as an extra argument that keeps the temporary result:
unsigned long factorial_tail_recursive(
unsigned long n, // number to calculate factorial
unsigned long temp_result // accumulated result
)
{
return n == 0? tmp_result
: factorial_tail_recursive( n-1, n*temp_result );
}
// syntactic sugar to offer the same interface
unsigned long factorial( unsigned long n ) {
return factorial_tail_recursive( n, 1 ); // accumulated result initialized to 1
}
But then again, for that particular problem an efficient iterative solution is probably easier to get right. Just maintain the accumulated result in a temporary variable and loop until the argument is reduced to 1.