Show awareness of what a compiler has to do to translate recursive programming code
19.2 Recursion – How a Compiler Turns Recursive Code into Machine Instructions
What is Recursion?
Recursion is a programming technique where a function calls itself to solve a problem. Think of a set of Russian nesting dolls: each doll contains a smaller one, and the process repeats until the smallest doll (the base case) is reached.
Example (Java‑style pseudocode):
int factorial(int n) {
if (n == 0) return 1; // base case
return n * factorial(n - 1); // recursive call
}
Mathematically: $n! = n \times (n-1)!$, with $0! = 1$.
Why Does a Compiler Care About Recursion?
A compiler must translate the high‑level recursive calls into low‑level machine code that the CPU can execute. This involves:
- Creating a call stack to keep track of each function invocation.
- Allocating space for local variables and return addresses.
- Ensuring that the base case stops the recursion to avoid infinite loops.
- Optimising tail‑recursive calls to prevent stack overflow.
Compiler Pipeline for Recursive Functions
- Lexical Analysis – Breaks source code into tokens.
- Syntax Analysis – Builds an abstract syntax tree (AST).
- Semantic Analysis – Checks types, scopes, and ensures the recursion is well‑formed.
- Intermediate Representation (IR) – Translates the AST into a lower‑level form (e.g., three‑address code).
- Optimization – Detects tail recursion and may convert it to a loop.
- Code Generation – Emits machine code or bytecode, handling stack frame layout.
How a Recursive Call is Implemented at Runtime
| Stack Frame | Contents |
|---|---|
| Return Address | Location to resume after factorial returns. |
Argument n |
Current value of n. |
| Local Variables | Space for any temporary data. |
When factorial(3) is called, the stack grows like this:
- Call
factorial(3)→ push frame withn=3. - Inside, call
factorial(2)→ push new frame. - Repeat until
factorial(0)→ base case, return 1. - Unwind: each frame multiplies its
nby the result from the deeper call.
Tail Recursion & Compiler Optimisation
Tail recursion occurs when the recursive call is the last action in the function:
int sumTail(int n, int acc) {
if (n == 0) return acc;
return sumTail(n - 1, acc + n); // tail call
}
A compiler can transform this into a loop, eliminating the need for new stack frames and preventing stack overflow.
Exam Tip Box
🔍 Remember: When answering recursion questions, always:
- Identify the base case and explain why it stops the recursion.
- Show the call stack growth for a few sample inputs.
- Discuss tail recursion optimisation and its effect on stack usage.
- Use LaTeX notation for mathematical expressions to demonstrate clarity.
💡 Bonus: If the question asks about compiler optimisation, mention tail‑call elimination and how it turns recursion into iteration.
Revision
Log in to practice.