Project 2.08 Section 2 ⚡ Embedded Relevance: High bool Bitfields Bitmasks std::bitset Register Bit Packing

2.08 bool Size Overhead (1 Byte) vs Bitfields & std::bitset for Packed Bitmasks

Executive Summary: Exploring the boolean data type. We analyze why sizeof(bool) occupies a full 8 bits (1 byte) in memory rather than 1 single bit due to byte-addressability, and demonstrate how to pack 8 boolean flags into a single byte using bitwise bitmasks and C++ bitfields.

💻 1. Annotated Source Code

#include <iostream>
using namespace std;

int main() {
	bool isRaining = true;
	cout << boolalpha;

	cout << isRaining << endl;
	return 0;
}

📐 2. Architecture & UML Class Model

📐 Boolean Bitfield Compression & 1-Byte Packing Model
+ Public - Private # Protected
<<struct>> BitfieldFlags 1-Byte Packed Struct
+isReady : uint8_t : 1
+hasError : uint8_t : 1
+isArmed : uint8_t : 1
+mode : uint8_t : 2
-reserved : uint8_t : 3
+printFlags() : void const

📚 3. Core C++ Concepts Deep-Dive

1. sizeof(bool) is 1 Byte

Even though a boolean holds only 1 bit of information (0 or 1), the CPU's smallest addressable memory unit is a byte (8 bits). Storing 8 independent bool variables consumes 8 bytes of RAM.

2. Bitfield Structures

C++ bitfields allow specifying exact bit widths for structure members: uint8_t flag : 1;.

⚡ 4. Embedded Systems & Hardware Reality

1. Register Bit Packing with Bitmasks

Microcontroller hardware control registers (e.g. GPIO MODER, CR1) pack dozens of configuration flags into a single 32-bit word. Bitwise operations (|, &, ~, ^) configure registers without wasting RAM.

💡 5. Production-Ready Embedded Refactoring

Packed 8-flag status register (1 Byte Total):

💡 Production-Ready Refactor
#include <cstdint>

struct SystemFlags {
    uint8_t power_good    : 1;
    uint8_t wifi_connected: 1;
    uint8_t sd_card_ready : 1;
    uint8_t motor_fault   : 1;
    uint8_t over_temp     : 1;
    uint8_t reserved      : 3;
}; // Exactly 1 byte in SRAM!

📝 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 does a single 'bool' variable in C++ occupy 1 full byte (8 bits) in memory instead of 1 bit?
A Modern CPU architectures are byte-addressable; individual bits cannot have unique memory addresses
B Because bool is a 64-bit float internally
C To store Unicode characters
D Because C++ forbids binary storage
Detailed Explanation: CPU memory pointers address byte boundaries (8 bits). Single bits cannot be directly addressed by pointer, so bool occupies 1 byte.
Q2. How much RAM do 8 independent 'bool' variables consume vs a single uint8_t bitmask byte?
A 8 bools consume 8 bytes (64 bits); a bitmask consumes exactly 1 byte (8 bits), saving 87.5% RAM
B Both consume 1 byte
C 8 bools consume 32 bytes
D Bitmasks consume more RAM
Detailed Explanation: 8 individual bool variables take 8 bytes (64 bits), whereas a packed uint8_t stores all 8 flags in 1 single byte.
Q3. Which bitwise operator is used to set bit 3 (0x08) of a hardware register to 1 without altering other bits?
A Bitwise OR: REG |= (1UL << 3)
B Bitwise AND: REG &= (1UL << 3)
C Bitwise NOT: REG = ~3
D Bitwise XOR: REG ^= 3
Detailed Explanation: Bitwise OR (REG |= (1UL << 3)) sets target bits to 1 while leaving all other bits unaffected.
Q4. Which bitwise operator is used to clear bit 4 (0x10) of a register to 0 without modifying any other bits?
A Bitwise AND with inverted mask: REG &= ~(1UL << 4)
B Bitwise OR: REG |= (1UL << 4)
C Bitwise XOR: REG ^= (1UL << 4)
D Addition: REG += 4
Detailed Explanation: REG &= ~(1UL << 4) creates a bitmask with bit 4 cleared to 0 and all other bits 1, clearing bit 4 safely.