Project 5.02 Section 5 ⚡ Embedded Relevance: Critical Pass-by-Value Pass-by-Reference const& Stack Frames Memory Footprint

5.02 Pass-by-Value Copy Overhead vs Pass-by-Reference & const& in Microcontroller RAM

Executive Summary: Comprehensive comparative study of the three parameter passing schemes: pass-by-value, pass-by-reference (&), and pass-by-const-reference (const &). We analyze assembly instruction differences, stack frame memory consumption, and reference aliasing in safety-critical systems.

💻 1. Annotated Source Code

#include <iostream>
using namespace std;

void valueChanged1(int someNum);
void valueChanged2(int& someNum);  // & means 'pass by reference'

int main() {
	int myNumber = 20;

	cout << "Before valueChanged1 call, myNumber is " << myNumber << endl;
	valueChanged1(myNumber);
	cout << "After valueChanged1 call, myNumber is " << myNumber << endl;

	cout << "\n-------------------------------------------\n";

	cout << "Before valueChanged2 call, myNumber is " << myNumber << endl;

	valueChanged2(myNumber);

	cout << "After valueChanged2 call, myNumber is " << myNumber << endl;

	return 0;
}

void valueChanged1(int someNum) {
	someNum = 100;
	cout << "Inside valueChanged1, someNum is " << someNum << endl;
}

void valueChanged2(int& someNum) {
	someNum = 100;
	cout << "Inside valueChanged2, someNum is " << someNum << endl;
}

📐 2. Architecture & UML Class Model

📐 Pass-by-Value vs Pass-by-Reference Assembly Mechanics
+ Public - Private # Protected
<<compilation-unit>> PassingSchemesUnit Calling Convention
(none / stateless)
+passByValue(x: int32_t) : void (Local register copy in R0)
+passByRef(x: int32_t&) : void (Passes memory address, stores via STR)
+passByConstRef(x: const int32_t&) : void (Zero-copy read-only)

📚 3. Core C++ Concepts Deep-Dive

1. Pass-by-Value

A complete copy of the argument is constructed in the callee's stack frame. Modifications inside the function do NOT affect the caller's variable.

2. Pass-by-Reference (T&)

Passes an alias (internally implemented as a pointer). Modifications inside the function directly alter the caller's variable.

3. Pass-by-Const-Reference (const T&)

Passes an alias with read-only guarantees. Prevents copying large structures while preventing accidental modifications.

⚡ 4. Embedded Systems & Hardware Reality

1. The Embedded Rule of Thumb

  • Primitive Types ($\le 4$ bytes): Pass by value (int, float, uint32_t). They fit directly inside CPU registers (R0-R3), requiring zero pointer indirection.
  • Aggregates & Structs ($> 4$ bytes): Pass by const reference (const SensorPacket&). Passing by value copies bytes onto the stack, increasing execution time and RAM usage.

💡 5. Production-Ready Embedded Refactoring

Idiomatic passing schemes in embedded systems:

💡 Production-Ready Refactor
#include <cstdint>

struct CanMessage {
    uint32_t id;
    uint8_t  payload[8];
    uint8_t  dlc;
};

// 1. Primitive: Pass-by-value (fits in R0)
void setFilterId(uint32_t id) noexcept;

// 2. Struct: Pass-by-const-ref (passes 4-byte pointer; avoids 16-byte copy)
void transmitCan(const CanMessage& msg) noexcept;

// 3. Mutator: Pass-by-ref (modifies caller's object directly)
void readCan(CanMessage& out_msg) noexcept;

📝 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. Why is passing a 64-byte telemetry struct by value suboptimal on an embedded microcontroller?
A The compiler must copy all 64 bytes onto the stack, wasting clock cycles and consuming precious stack SRAM
B The struct will be corrupted during the call
C C++ forbids passing structs by value
D Passing by value deletes the original struct
Detailed Explanation: Pass-by-value creates a full duplicate of the struct on the stack, consuming stack RAM and CPU cycles for memory copying.
Q2. For a 32-bit integer (uint32_t), why is pass-by-value generally faster than pass-by-const-reference on ARM Cortex-M?
A Pass-by-value loads the value directly into register R0, whereas pass-by-reference passes an address that requires an extra dereferencing memory load instruction
B Pass-by-value uses floating point registers
C Pass-by-reference always allocates heap memory
D Pass-by-value disables interrupts
Detailed Explanation: Passing a 4-byte integer by value puts it directly into a register (R0), while passing by reference passes a pointer that forces an extra LDR memory read.
Q3. What is 'pointer aliasing' in C++ parameter passing?
A When two reference/pointer parameters in a function point to the same memory location, preventing certain compiler loop optimizations
B When a pointer points to address 0x00000000
C When a pointer is deleted twice
D When a function has more than 4 parameters
Detailed Explanation: Aliasing occurs when multiple pointers/references refer to the same object. The compiler must assume writes through one pointer may modify the other, limiting optimization.
Q4. What does passing by non-const reference (T&) signal in function API design?
A The function intends to modify the caller's argument directly (acting as an in-out or output parameter)
B The function will delete the caller's object
C The function executes in background threads
D The function returns a pointer to Flash ROM
Detailed Explanation: Non-const reference parameters (T&) indicate that the function will mutate the caller's object in place.