Open In App

Nested Functions in C

Last Updated : 27 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Nesting of functions refers to placing the definition of the function inside another functions. In C programming, nested functions are not allowed. We can only define a function globally.

Example:

C
#include <stdio.h>

int main() {
    void fun(){
        printf("GeeksForGeeks");
    }
    fun();
    return 0;
}


Output

main.c:4:15: error: function definition is not allowed here
    4 |     void fun(){
      |               ^
main.c:7:5: error: use of undeclared identifier 'fun'
    7 |     fun();
      |     ^

The above code gives error because defining a function inside another function is not possible in C programming language.

GCC Extension for Nested Function

GCC compiler provides feature of nesting functions as an extension even though it is not the part of standard C.

Example:

C
#include <stdio.h>

int main() {
    printf("Outer Function\n");
    
    // Defining inner function
    void inner() {
        printf("Inner Function\n");
    }
    
    // Calling nested functions
    inner();
    return 0;
}

Output
Outer Function
Inner Function

If you want to declare the function before its definition, then use auto keyword.

C
// Declaring inner function
auto void inner();

Nested Function Scope and Lifetime

The scope of nested function is limited to the outer function in which it is declared. Only the outer function can call the nested function directly. But if we pass the pointer of the nested function to some other function, then we can call it even outside the enclosing function. It is because GCC uses the concept of trampoline to implement nested functions.

Trampolines are the small piece of code generated at runtime when the nested functions are called outside their scope. When the address of a nested function is taken, a trampoline is created, and its address is returned which contain two information:

  • The real address of nested function code.
  • The address of enclosing function stack frame.

Due to this, the nested function can also access the variables from the enclosing function. It is called lexical scoping.

Example:

C
#include <stdio.h>

void print(void (*fp)()) {
    fp();    
}

void outer(int x) {
    int y = 10;
    void inner() {
        printf("%d\n", x + y);
    }
    
    // Creating pointer to inner()
    void (*fp)() = &inner;
    
    // Passing fp pointer to other function
    print(fp);
}

int main() {
    
    // Calling enclosing function
    outer(5);
    return 0;
}

Output
15

The above program defines a nested function inner() inside outer() that adds two numbers x and y (local variables of outer) and prints the result. When it creates a pointer to inner(), a trampoline is created and passed to the function print(), which then calls inner() to display the sum. It was successfully able to determine the sum of x and y in the function print() even though these variables being outside its immediate scope.

Lifetime

The nested function, like any other function, exists in the code as long as the program runs, but its ability to work properly depends on whether the outer function’s stack frame is present or not. So, it can be said that its effective lifetime is till the stack frame of enclosing function exists.

For example, the below program results in error:

C
#include <stdio.h>

void (*outer(int x))() {
    int y = 10;
    void inner() {
        printf("%d\n", x + y);
    }
    
    // Return the address of inner
    return &inner;
}

int main() {
    // Get function pointer from outer
    void (*fp)() = outer(5);
    
    // Call the nested function via  pointer
    fp();
    return 0;
}


Output

segmentation fault

This is because when we call the function inner() through function pointer fp, the stack frame of outer() is already destroyed. If we do not access the variables of enclosing function, even this program can run without errors.

C
//Driver Code Starts{
#include <stdio.h>

void (*outer(int x))() {
    int y = 10;
//Driver Code Ends }

    void inner() {
        
        // Not accessing outer()'s variables
        printf("Hello from inner()");
    }

//Driver Code Starts{
    return &inner;
}

int main() {
    void (*fp)() = outer(5);
    fp();
    return 0;
}
//Driver Code Ends }

Output
Hello from inner()


Next Article
Article Tags :

Similar Reads