Project 2.05 Section 2 ⚡ Embedded Relevance: Critical Arithmetic Integer Promotion Signed Overflow UB Saturating Math Assembly

2.05 Integer Promotion Rules, Signed Overflow Undefined Behavior & Saturating Math

Executive Summary: Analyzing arithmetic operators (+, -, *, /, %). We explore C++ Integer Promotion rules (small integer types are promoted to int during math), Signed Overflow Undefined Behavior (UB) which compilers exploit to optimize away safety checks, and ARM Cortex-M hardware saturating arithmetic instructions (QADD, QSUB).

💻 1. Annotated Source Code

#include <iostream>
using namespace std;

int main() {
	// + addition
	// - subtraction
	// * multiplication 
	// / division
	// % modulus (remainder)

	int a = 10;
	int b = 3;

	int sum = a + b;
	int difference = a - b;
	int product = a * b;
	int quotient = a / b;
	int remainder = a % b;

	// +=  Add and assign
	// -=  Subtract and assign
	// *=  Multiply and assign
	// /=  Divide and assign
	// %=  Modulus and assign


	int result = 10;
	result += 15;   // result = result + 15;
	cout << "Result: " << result << endl;

	cout << "Sum: " << sum << endl;
	cout << "Difference: " << difference << endl;
	cout << "Product: " << product << endl;
	cout << "Quotient: " << quotient << endl;
	cout << "Remainder: " << remainder << endl;


	int myInt = 5;
	myInt++;   //increment operator, same as myInt += 1;  or myInt = myInt + 1;
	cout << myInt << endl;

	myInt--;   //decrement operator, same as myInt -= 1; or myInt = myInt - 1;

	cout << myInt << endl;


	int myNum = 10;
	myNum += 5;
	myNum *= 2;
	myNum *= 2;
	myNum *= 2;

	cout << "Final value: " << myNum << endl;



	return 0;
}

📐 2. Architecture & UML Class Model

📐 ALU Arithmetic Pipeline & Overflow Guard Model
+ Public - Private # Protected
<<compilation-unit>> ArithmeticEngine ALU Operations
-opA : int32_t
-opB : int32_t
+add(a: int32_t, b: int32_t) : int32_t
+subtract(a: int32_t, b: int32_t) : int32_t
+multiply(a: int32_t, b: int32_t) : int32_t
+divide(a: int32_t, b: int32_t) : int32_t
+modulo(a: int32_t, b: int32_t) : int32_t
<<embedded-dsp>> SaturatingMath QADD / QSUB
+INT32_SAT_MAX : const int32_t
+INT32_SAT_MIN : const int32_t
+addSaturate(a: int32_t, b: int32_t) : int32_t
+subSaturate(a: int32_t, b: int32_t) : int32_t
🔗 Architectural Relationships & Hierarchy
ArithmeticEngine ─ ─ > refactors to ─ ─ > SaturatingMath

📚 3. Core C++ Concepts Deep-Dive

1. Integer Promotion

In C++, arithmetic operations on types smaller than int (uint8_t, int8_t, int16_t) automatically promote operands to int before computation.

2. Signed vs Unsigned Overflow

  • Unsigned Overflow: Well-defined by the standard to wrap around modulo $2^N$.
  • Signed Overflow: UNDEFINED BEHAVIOR (UB). The compiler assumes signed overflow never occurs, and may optimize away sanity/safety bounds checks!

⚡ 4. Embedded Systems & Hardware Reality

1. Hardware Saturating Arithmetic (DSP QADD / QSUB)

In audio and sensor processing, wrap-around overflow causes deafening acoustic clicks or motor runaway. ARM Cortex-M DSP instructions clamp out-of-range results to maximum/minimum limits in a single clock cycle.

💡 5. Production-Ready Embedded Refactoring

Software saturating integer addition:

💡 Production-Ready Refactor
#include <cstdint>
#include <algorithm>

// Saturating addition: Clamps to 255 rather than wrapping to 0
constexpr uint8_t add_saturating_u8(uint8_t a, uint8_t b) noexcept {
    uint16_t sum = static_cast<uint16_t>(a) + b;
    return static_cast<uint8_t>(sum > 255 ? 255 : sum);
}

📝 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 the behavior of signed integer overflow (e.g. INT_MAX + 1) in standard C++?
A Undefined Behavior (UB); the compiler may optimize away downstream bounds checks assuming it is impossible
B Guaranteed to wrap around to INT_MIN
C Throws a std::overflow_error exception
D Sets the integer to 0
Detailed Explanation: Signed overflow is Undefined Behavior in C++. Compilers are free to assume overflow never happens, often eliminating critical safety range checks.
Q2. What happens under C++ Integer Promotion rules when two uint8_t variables are added (uint8_t a = 100, b = 200; auto c = a + b;)?
A Both operands are promoted to 'int' (32 bits), and the expression evaluates to an 'int' with value 300
B The result immediately wraps to uint8_t (44)
C A compile-time type mismatch occurs
D The variables are cast to float
Detailed Explanation: Under integer promotion rules, types narrower than int are promoted to int before arithmetic evaluation.
Q3. What is 'saturating arithmetic' in embedded DSP and motor control algorithms?
A Arithmetic where results that exceed the maximum representable value clamp to MAX instead of wrapping around to 0 or negative numbers
B Arithmetic performed in liquids
C Arithmetic that disables the CPU clock
D Floating-point math in software
Detailed Explanation: Saturating arithmetic clamps values at bounds limits (e.g. 255 for uint8_t), preventing sudden sign inversion or wrap-around glitches in control loops.
Q4. What does unsigned integer overflow guarantee in C++?
A Deterministic modulo arithmetic wrap-around (e.g. 255 + 1 == 0 for uint8_t)
B Undefined Behavior
C Hardware HardFault trap
D Stack frame corruption
Detailed Explanation: Unsigned integer arithmetic in C++ is guaranteed to wrap modulo $2^N$ according to the standard.