Open In App

Tail Call Optimisation in C

Last Updated : 06 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In C programming, Tail Call Optimization (TCO) is a technique that eliminates the need for an additional stack frame to store the data of another function by reusing the current function’s stack frame. This optimization technique is only possible for tail function calls.

What is Tail Call?

The tail call is the type of function call where another function is called as the last action of the current function. Here, the function call is present as the last statement at the end of the current function’s body.

The tail call optimization is most useful in tail recursion where the last thing a function does is to call itself. In such cases, it converts the recursive function to an iterative function by reusing the current stack frame for all function calls. It helps in reducing the space complexity of the recursive function.

Example

Let’s consider a hypothetical scenario, We need to call a recursive function that calculates the factorial of a number modulo a prime number say ‘prime’.

C




// C Program to illustrate Tail Call Optimization
#include <stdio.h>
 
// Program to find factorial of a number n modulo prime
int factorial(int n, int prime)
{
    if (n <= 1) {
        // base case
        return 1;
    }
 
    return (n * factorial(n - 1, prime) % prime) % prime;
}
 
int main()
{
 
    // Calling for the factorial of 5
    int result = factorial(5, 1000000007);
    printf("%d\n", result);
    return 0;
}


Output

120

This program will take up a lot of time and a significant amount of memory. Let us look at the function call stack for n = 6.

main()
       \
  factorial(5)
          \
    factorial(4)
             \
      factorial(3)
                \
        factorial(2)
                  \
           factorial(1)

Space Complexity: O(n)

So, without an optimization technique, a function like this would stack overflow for large values of n.

Optimizing the Above Function

This is where TCO comes into the picture, using which the compiler can avoid the creation of a new stack frame, under the condition that the call made is the last operation in the function in which it is called.

TCO technique uses the current function’s stack frame for the new function call. This helps prevent stack overflow errors for deep recursive calls and thus increases the efficiency of the program.

C




// C program to illustrate Tail Call Optimisation
#include <stdio.h>
 
// this function calculates factorial modulo prime
int factorial(int store, int num, int prime) {
  if (num < 1) {
    // Base case
    return store;
  }
 
  return factorial((store%prime * num%prime)%prime, num - 1, prime);
}
 
int main(){
     
      int result = factorial(1,5,1000000007);
      printf("%d\n", result);
      return 0;
}


Output

120

Explanation

The existing frame can be directly over-written by the compiler: the old value of num is multiplied by the old value of store and the result is written back into the store variable. The compiler can now decrement num by overwriting the previous value and jump to the beginning of the factorial function. Note that here, we are making sure that instead of the multiplication operation, the function call is the last operation in the above code that needs to be executed.

Note: Not all recursive functions can be optimized using such techniques. The reason is that complex recursive functions where the recursive call is not the last operation and additional operations after the call are present are not suitable for Tail Call Optimization.

Tail-Call-Optimisation-in-C

Tail Call Optimization in C

Impact on Space Complexity

Since there is no need to preserve stack frames of the previous function call, the new function call’s stack frame overrides the stack frame of the previous call, constant space is required, i.e. O(1) instead of O(n).

Advantages of Tail Call Optimization

  • Significant reduction in stack space usage, reducing the risk of running into stack overflow.
  • Improvement in performance due to reduction in overhead of managing stack frames, leading to faster execution.
  • Supports functional programming, where recursion is commonly used for solving problems.

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads