2.03 Fundamental Types, Implementation-Defined Widths vs Fixed-Width <cstdint> Types
Executive Summary: Exploring fundamental C++ data types (int, double, char, bool). We demonstrate why non-standardized integer widths (e.g. sizeof(int) varies between 16-bit, 32-bit, and 64-bit architectures) cause critical cross-platform bugs, and enforce fixed-width integer types () across all embedded firmware.
💻 1. Annotated Source Code
#include <iostream> //using namespace std; int main() { int myInt; // declaration double myDouble = 3.14159; myInt = 15; // initialization int x = 10; // copy initialization (assignment) int y(10); // direct initialization int z{ 10 }; // uniform (brace) initialization int ok = 3.14; int bad{ 3.14 }; double pi = 3; //widening conversion (no loss of data) double stateTaxRate = 0.06; //state_tax_rate std::cout << myInt << std::endl; std::cout << myDouble << std::endl; return 0; }
📐 2. Architecture & UML Class Model
<<struct>>
TypeMemoryLayout
Stack Frame Layout
Attributes / Data Members
+myInt : int32_t (4 bytes @ SP+0)
+myDouble : double (8 bytes @ SP+4)
+myChar : char (1 byte @ SP+12)
+myBool : bool (1 byte @ SP+13)
-padding : uint8_t[2] (Alignment Pad)
Operations / Methods
+inspectSizes() : void
+printMemoryAddresses() : void
📚 3. Core C++ Concepts Deep-Dive
1. Fundamental Types in C++
In C++, fundamental types like int, short, long have implementation-defined bit widths. An int is 16 bits on an 8-bit AVR microcontroller, but 32 bits on an ARM Cortex-M.
2. Fixed-Width Integers (<cstdint>)
The <cstdint> header guarantees exact bit-widths across all compilers and CPU architectures (e.g. uint8_t, int16_t, uint32_t, uint64_t).
⚡ 4. Embedded Systems & Hardware Reality
1. MISRA C++:2008 Rule 3-9-2
The basic numerical types (int, short, long) shall not be used; fixed-width types from <cstdint> (or typedefs indicating size and signedness) must be used exclusively to guarantee deterministic hardware bitmasks and avoid porting bugs.
💡 5. Production-Ready Embedded Refactoring
Explicit fixed-width register structures:
💡 Production-Ready Refactor
#include <cstdint> // Deterministic width across 8-bit, 16-bit, 32-bit, and 64-bit CPUs struct AdcChannelConfig { uint8_t channel_number; // Exactly 8 bits (0-255) uint16_t sampling_cycles;// Exactly 16 bits (0-65535) uint32_t calibration_val;// Exactly 32 bits };
📝 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 'int' avoided in embedded systems in favor of 'int32_t' or 'uint16_t' from <cstdint>?
Detailed Explanation:
Standard C++ allows
int to be 16 or 32 bits depending on architecture. <cstdint> guarantees explicit bit-widths everywhere.
Q2. What is the value range of an 8-bit unsigned integer (uint8_t)?
Detailed Explanation:
An unsigned 8-bit integer ($2^8 = 256$ distinct values) spans from 0 to 255.
Q3. Which header must be included to access types like uint32_t, int16_t, and uint8_t in modern C++?
Detailed Explanation:
<cstdint> is the standard C++ header providing exact-width integer typedefs.
Q4. What is 'size_t' in C++?
Detailed Explanation:
size_t is the unsigned architecture-native integer type returned by sizeof and container size methods.