Project 11.06 Section 11 ⚡ Embedded Relevance: Critical Templates Generic Code Code Bloat Flash ROM Zero-Cost Inlining C++17 if constexpr

11.06 Generic Programming vs Flash Memory Overhead in Embedded Microcontrollers

Executive Summary: Exploring generic function and class templates. We examine compile-time monomorphization, compare zero-overhead inlining against Flash ROM binary expansion (template code bloat), and demonstrate techniques to share implementation code across instantiations.

💻 1. Annotated Source Code

#include <iostream>
#include <string>

using namespace std;

//double getBigger(double a, double b);
//int getBigger(int a, int b);
//string getBigger(string a, string b);

template <class T>
T getBigger(T a, T b) {
	return (a > b) ? a : b;
}

template <class T>
T getSmaller(T a, T b) {
	return (a < b) ? a : b;
}

int main() {

	double d1 = 3.14;
	double d2 = 5.55;
	int i1 = 11;
	int i2 = 9;
	string s1 = "Alice";
	string s2 = "John";


	double biggerDub = getBigger(d1, d2);
	int biggerInt = getBigger(i1, i2);
	string biggerStr = getBigger(s1, s2);

	double smallerDub = getSmaller(d1, d2);
	int smallerInt = getSmaller(i1, i2);
	string smallerString = getSmaller(s1, s2);


	cout << "Bigger items:" << endl;
	cout << "\t" << biggerDub << "\n\t" << biggerInt << "\n\t" << biggerStr << endl;

	cout << "Smaller items:" << endl;
	cout << "\t" << smallerDub << endl;
	cout << "\t" << smallerInt << endl;
	cout << "\t" << smallerString << endl;

	return 0;
}

//double getBigger(double a, double b) {
//	return (a > b) ? a : b;
//}
//
//int getBigger(int a, int b) {
//	return (a > b) ? a : b;
//}
//
//string getBigger(string a, string b) {
//	return (a > b) ? a : b;
//}

📐 2. Architecture & UML Class Model

📐 Function & Class Template Specialization Architecture
+ Public - Private # Protected
<<template functions>> TemplateEngine Monomorphization Pipeline
(none / stateless)
+printGeneric<T>(val: const T&) : void
+sumGeneric<T>(a: T, b: T) : T
<<template class>> GenericBox<T> Generic Container
-item : T
+GenericBox(initialItem: const T&)
+getItem() : T const
+setItem(newItem: const T&) : void

📚 3. Core C++ Concepts Deep-Dive

1. Compile-Time Monomorphization

Unlike Java or C# generics (which use type erasure at runtime), C++ templates are instantiated at compile-time. The compiler generates an entirely dedicated copy of the machine code for each unique type (print<int>, print<double>, print<string>).

⚡ 4. Embedded Systems & Hardware Reality

1. The Flash ROM Code Bloat Hazard

If a large template class is instantiated with 10 different types on a 64KB Flash microcontroller, the compiler will emit 10 distinct copies of the class binary, easily overflowing available Flash ROM.

💡 Embedded Optimization: Template Hoisting (Common Base Idiom)

Extract all type-independent code into a non-templated base class. The templated derived class only implements thin inline type-casts, sharing a single binary implementation in Flash ROM!

💡 5. Production-Ready Embedded Refactoring

Template hoisting pattern reducing Flash ROM consumption:

💡 Production-Ready Refactor
// Non-templated base: Single copy in Flash ROM (.text)
class CircularBufferBase {
protected:
    void* buffer_;
    size_t head_ = 0, tail_ = 0, capacity_;
    void advanceTail() { tail_ = (tail_ + 1) % capacity_; }
};

// Thin templated wrapper: Inlined with ZERO extra Flash code
template <typename T, size_t N>
class CircularBuffer : public CircularBufferBase {
public:
    CircularBuffer() { buffer_ = storage_; capacity_ = N; }
    void push(T val) { storage_[head_] = val; head_ = (head_ + 1) % N; }
private:
    T storage_[N];
};

📝 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 'template code bloat' in embedded microcontroller firmware?
A A compiler warning when template parameters are too long.
B The generation of multiple redundant machine-code copies in Flash ROM for every unique template type instantiation.
C An error caused by insufficient stack memory.
D A runtime exception thrown when templates exceed 1KB.
Detailed Explanation: Because C++ instantiates dedicated machine code for every type passed to a template, instantiating templates with numerous types can rapidly exhaust MCU Flash ROM.