5.09 In-Out Parameters, Multiple Return Values & Struct Results vs std::tuple
Executive Summary: Exploring functions that return multiple values via pass-by-reference out-parameters. We compare legacy out-parameters with modern C++17 structured bindings and small return structs.
💻 1. Annotated Source Code
#include <iostream> using namespace std; void threeTimesN(int input, int& output); int main() { int myInput = 50; int myOutput; threeTimesN(myInput, myOutput); cout << "After threeTimesN, myOuput is " << myOutput << endl; return 0; } void threeTimesN(int input, int& output) { output = input * 3; }
📐 2. Architecture & UML Class Model
<<compilation-unit>>
ParameterChallengeUnit
Out Parameters
Attributes / Data Members
(none / stateless)
Operations / Methods
+computeStats(a: int, b: int, sum: int&, product: int&) : void
📚 3. Core C++ Concepts Deep-Dive
1. Out-Parameters via References
Functions requiring multiple output values historically passed references or pointers as out-parameters (void getCoordinates(int& x, int& y)).
2. Modern Alternative: Value Structs & Structured Bindings
In C++17, returning a small struct by value is optimized via Return Value Optimization (RVO), enabling clean structured binding syntax: auto [x, y] = getCoordinates();.
⚡ 4. Embedded Systems & Hardware Reality
1. RVO and Register Packing
Under the ARM AAPCS, small return structs containing two 32-bit integers are returned packed in registers R0 and R1 with 0 RAM overhead.
💡 5. Production-Ready Embedded Refactoring
Modern struct return with structured binding support:
💡 Production-Ready Refactor
#include <cstdint> struct Coordinate2D { int32_t x; int32_t y; }; // Returned packed in registers R0 and R1 (0 stack traffic!) constexpr Coordinate2D readGpsPosition() noexcept { return Coordinate2D{12345, 67890}; }
📝 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 feature introduced in C++17 allows cleanly unpacking members from a returned struct (auto [x, y] = getPos())?
Detailed Explanation:
Structured bindings (C++17) allow directly unpacking struct members into local variables.
Q2. How are small 2-word structs returned by value on ARM Cortex-M processors?
Detailed Explanation:
Under AAPCS, return values up to 8 bytes (two 32-bit words) are passed back directly in CPU registers R0 and R1.
Q3. Why is returning a struct by value often cleaner than using multiple non-const reference out-parameters?
Detailed Explanation:
Returning structs keeps data flow clear and functional, avoiding side-effect bugs and compiler aliasing penalties.
Q4. What is Return Value Optimization (RVO)?
Detailed Explanation:
RVO constructs the return value directly in the destination memory allocated by the caller, achieving zero copy overhead.