5.04 Recursive Stack Frame Growth, Call Depth Hazards & constexpr Compile-Time Evaluation
💻 1. Annotated Source Code
#include <iostream> using namespace std; int factorial(int num); int main() { int result = factorial(6); cout << "The factorial(6) is " << result << endl; return 0; } int factorial(int num) { if (num > 1) { return num * factorial(num - 1); } return 1; }
📐 2. Architecture & UML Class Model
📚 3. Core C++ Concepts Deep-Dive
1. Recursive Call Stack Mechanics
Each recursive function call creates a new stack frame storing local variables, parameters, and the return address. A recursion depth of $N$ consumes $O(N)$ stack memory.
2. Iterative & Tail-Call Alternatives
Iterative loops require $O(1)$ stack space. When the recursive call is the absolute last operation (tail recursion), optimizing compilers can reuse the existing stack frame (Tail-Call Optimization - TCO).
⚡ 4. Embedded Systems & Hardware Reality
1. Why Recursion is Banned in Embedded Systems
In embedded systems and RTOS tasks, stack sizes are statically allocated and very small (e.g. 512 to 2048 bytes). Unbounded or deep recursion quickly exceeds the stack limit, silently clobbering adjacent RAM and causing catastrophic system crashes.
🚫 MISRA C++:2008 Rule 7-5-4 & NASA C Safety Rule #3
Functions shall not call themselves, either directly or indirectly. Execution bounds and stack depth must be deterministically provable.
2. Compile-Time constexpr Evaluation
Modern C++ allows computing mathematical constants at compile time, consuming 0 clock cycles and 0 stack frames at runtime.
💡 5. Production-Ready Embedded Refactoring
Compile-time constexpr factorial calculation:
#include <cstdint> // Evaluated 100% at compile-time; 0 runtime stack usage! constexpr uint32_t factorial(uint32_t n) noexcept { uint32_t result = 1; for (uint32_t i = 2; i <= n; ++i) { result *= i; } return result; } // Stored as an immediate constant in Flash ROM constexpr uint32_t FACT_6 = factorial(6); // Emits MOV R0, #720
📝 Knowledge Verification Quiz
Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.
constexpr functions with constant arguments are computed by the compiler during compilation, embedding results directly into the binary.