cfunctionstackstack-frame

In C, what happens to the stack when we have a return statement which returns a function call?


im uderstanding the stack in C lenguage, but I have a question; please look at this simple code:

#include <stdio.h>

void function(int x){
    if(x==0){
        return;
    }
    else{
        printf("x is equal to 1");
    }
    return function(x-1);
}

void main(){
    function(1);
    return;
}

So, first the stack frame (or activation record) of main function its stored on the stack, when we call function(1) the stack frame of function(1) gets stored on the stack too; in the function(1) we enter the else statement and we encounter return function(0);, so my question is, what happens here?, the stack frame of function(1) gets popped from the stack because of the return statement and the stack frame of function(0) gets stored in the stack? or the stack still has the stack frames of main and function(1) and the stack frame of function(0) gets stored as well (having now 3 stack frames in the stack)?

If the second possibility is the right one, so in function(0) we enter the if statement and because of return, function(0) stack frame gets popped from the stack, and then function(1) gets popped and finally main gets popped from the stack?


Solution

  • If your compiler and the settings you compile with support it, tail call optimization1 may occur, and in your case the stack space for function(0) reuses the stack space for function(1).

    However, this is not guaranteed in C and should not be counted on.

    Without this optimization, all of your stack frames will accrue, and given a sufficiently large initial value passed into function you will get a stack overflow error.

    As noted by Jonathan Leffler in comments, you should not return the result of the recursive call, as function is a void function. Further, the else is extraneous given the way control flow is handled.

    void function(int x) {
        if (x == 0) {
            return;
        }
        
        printf("x is equal to 1");   
        function(x-1);
    }
    

    1 recommended further reading: What is tail call optimization?