Nesting of functions means defining one function inside another function. In standard C, function definitions cannot be placed inside other functions.
- Nested function definitions are not allowed in standard C. Every function must be defined at the global (file) scope.
- Since functions cannot be nested, each function is defined separately and can be called from other functions when needed.
#include <stdio.h>
int main() {
void fun(){
printf("GeeksForGeeks");
}
fun();
return 0;
}
Output
GeeksForGeeks
The above code gives error standard compliant-compilers because defining a function inside another function is not possible in C programming language.
Syntax
void outer() {
// Statements
void inner() { // Invalid in standard C
// Statements
}
}
GCC Extension for Nested Function
GCC supports nested functions as a compiler-specific extension, even though they are not part of the C standard. Programs using nested functions may not work with other C compilers.
- Nested functions in GCC are useful when a helper function is needed only within another function, keeping it limited to that scope.
- Since this feature is non-standard, it reduces code portability and should be avoided if the program needs to compile on different C compilers.
#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
Nested Function Scope and Lifetime
- The scope of a nested function is limited to the outer function where it is defined, so it can normally be called only from within that outer function.
- If the address of a nested function is passed to another function, GCC allows it to be called outside the enclosing function by using trampolines.
Trampoline
A trampoline is a small piece of code generated at runtime by GCC when the address of a nested function is taken. It stores:
- The address of the actual nested function.
- The address of the enclosing function's stack frame.
Lexical Scoping
Because the trampoline keeps a reference to the enclosing function's stack frame, the nested function can directly access the local variables of its outer function. This behavior is known as lexical scoping.
#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
Explanation
- The program defines a nested function inner() inside outer() and passes its pointer to print(), where GCC creates a trampoline.
- The trampoline lets inner() access outer()'s local variables (x and y), so print() can successfully call inner() and print their sum.
Lifetime
The nested function exists throughout the program, but it works correctly only while the outer function's stack frame is active.
- Its effective lifetime lasts only until the enclosing function returns.
- After the outer function ends, accessing the nested function is unsafe because its stack frame no longer exists.
#include <stdio.h>
void outer(int x) {
int y = 10;
void inner() {
printf("%d\n", x + y);
}
inner(); // Safe: outer's stack frame still exists
}
int main() {
outer(5);
return 0;
}
Output
15
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.
//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()