Recursion Until Death!

When I first learned Assembly Language, I had a fear of blowing up the stack. Remember, back in the 8-bit microcomputer era that memory space was tight, maybe only part of 64K. A stack would have 1K of storage, if that. I think the stack size on my TRS-80 was 256 bytes. (An address was only two bytes wide.) This limitation meant that pushing too much data on the stack would blow up the computer.

Nothing would explode, of course; I love hyperbole. Even so, I was leery of pushing too much data on the stack. So, while I understood the concept of recursion, I remained fearful that if a function called itself too often the stack would explode and I’d be sweeping up bits from the floor behind the computer.

That never happened.

It never happened because I was careful. But when I obtained my first 16-bit computer, I harbored no fear of blowing up the stack. In fact, I must have at some point coded a program like the following just to test how robust the stack can be:

2026_07_11-Lesson.c

#include <stdio.h>

void recurse(int i)
{
    printf("%d\n",i);
    recurse(i+1);
}

int main()
{
    recurse(0);

    return 0;
}

This code provides an example of recursion. A poor example. The problem is that recursion doesn’t ever unwind: The function keeps calling itself until no more return addresses can be pushed onto the stack. Boom.

The code compiles cleanly under gcc, but clang issues an “infinite recursion” warning. Regardless, a program is built.

Here is the tail end of output from a sample run:

261834
261835
261836
261837
261838
Segmentation fault (core dumped)

On my test computer, the function called itself 261,838 times before the stack could hold no more values. The “Segmentation fault” means that an attempt was made to access memory outside of the program’s allocated space (the “segment”). The core is dumped. The program stops.

Other computers show different final values in the output, based on allocated stack space.

So how much stack space is there? To find out in Linux, use the ulimit -s command at the terminal:

$ ulimit -s
8192

The -s option outputs the stack size in kilobytes. (Use ulimit -a to see all limits set for the current terminal configuration.)

According to the output, the current terminal has a stack size of 8192K, or 8,388,608 bytes, which is a lot of storage.

It’s possible to use ulimit to change the stack size. For example:

ulimit -s 16384

When I made this change and ran the program again, here are the last few lines of output:

524090
524091
524092
524093
Segmentation fault (core dumped)

Obviously, the result is larger because the stack is larger and it took longer for recursion to explode.

By the way, changing the stack size affects only the current terminal configuration and its programs or “children.” Permanent changes to the stack size are made in the /etc/security/limits.conf file.

Recursion is something you can safely employ in your code — as long as it successfully unwinds itself. If necessary, you can allocate more stack storage, but I would be interested in see what type of program would merit such an increase.

Leave a Reply