Project 5.13 Section 5 ⚡ Embedded Relevance: Critical Scope Lifetime Static Variables Reentrancy .data vs .bss

5.13 Local vs Global Scope, Static Variables (.data/.bss) & Reentrancy Hazards

Executive Summary: Analyzing variable scope and lifetime: local (automatic stack), global, and local static storage. We analyze the memory map placement of static variables (.data vs .bss) and the severe reentrancy hazards of static variables in multi-threaded RTOS tasks.

💻 1. Annotated Source Code

#include <iostream>
using namespace std;

void someFunction(int aParam);

double myGlobalDouble = 3.1415;

int main() {

	int localToMain = 20;

	cout << "The local to main variable is: " << localToMain << endl;
	cout << "The global double (in main) is: " << myGlobalDouble << endl;

	someFunction(25);
	someFunction(28);
	someFunction(32);

	//cout << myLocalNum << endl;

	return 0;
}

void someFunction(int aParam) {
	int myLocalNum = 100;
	myLocalNum++;

	static int myStatic = 500;
	myStatic++;

	myGlobalDouble++;

	cout << "My local number: " << myLocalNum << endl;
	cout << "The parameter is: " << aParam << endl;
	cout << "Global double (in someFunction) is: " << myGlobalDouble << endl;
	cout << "myStatic: " << myStatic << endl;

	//localToMain++;
}

📐 2. Architecture & UML Class Model

📐 Variable Lifetime & Scope Resolution Model
+ Public - Private # Protected
<<compilation-unit>> ScopeResolver Lifetime Matrix
+globalVar : int32_t (.data section)
-staticVar : int32_t (.bss persistent)
+testScope() : void
+shadowDemo(globalVar: int) : void

📚 3. Core C++ Concepts Deep-Dive

1. Storage Duration Categories

  • Automatic (Stack): Created at block entry, destroyed at block exit.
  • Static (RAM): Allocated once at startup, persists for the entire program execution.
  • Dynamic (Heap): Allocated via new, persists until delete.

⚡ 4. Embedded Systems & Hardware Reality

1. The Reentrancy Hazard of Local Static Variables

A function containing a local static variable (static int counter = 0;) is NOT reentrant. If an interrupt routine (ISR) preempts the function and calls it again, or if two RTOS tasks execute it concurrently, the static variable will suffer race conditions.

2. Memory Placement: .data vs .bss

Initialized static variables live in .data (copied from Flash to RAM at boot). Uninitialized static variables live in .bss (zeroed at boot).

💡 5. Production-Ready Embedded Refactoring

Reentrant task-safe function design:

💡 Production-Ready Refactor
#include <cstdint>

// Reentrant: All state is passed via caller-provided context (Zero static state)
struct CounterContext {
    uint32_t count{0};
};

uint32_t incrementReentrant(CounterContext& ctx) noexcept {
    return ++ctx.count; // 100% thread-safe across independent tasks
}

📝 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.

Q1. What is a 'reentrant function' in embedded systems?
A A function that can be safely interrupted and called simultaneously by another task or ISR without corrupting data
B A function that calls itself recursively
C A function stored in ROM
D A function that has no arguments
Detailed Explanation: Reentrant functions rely only on caller-provided stack data and avoid shared static/global state, allowing safe concurrent execution.
Q2. Why does a function containing a local 'static int count = 0;' fail reentrancy checks in an RTOS?
A The static variable resides in shared global RAM; concurrent execution by multiple threads or ISRs produces race conditions
B Static variables cannot be modified
C Static variables are erased when an interrupt fires
D Static variables use double precision
Detailed Explanation: Local static variables share a single global memory location across all invocations, creating race conditions when called concurrently.
Q3. Where is an initialized global variable (int sensor_id = 42;) stored in the microcontroller memory map?
A .data section in RAM (initialized from Flash ROM during startup)
B .bss section in RAM
C .text section in ROM
D .stack section
Detailed Explanation: Initialized static/global variables reside in .data; their initial values are stored in Flash and copied into RAM by startup code.
Q4. What is the lifetime of a local variable declared inside a function body?
A Automatic lifetime: allocated on the stack when the enclosing block is entered and destroyed upon exit
B Permanent lifetime: exists until power-off
C Exists until explicitly deleted
D Exists for 1 millisecond
Detailed Explanation: Local variables have automatic storage duration, existing only while execution is inside their enclosing lexical block.