2.07 Short-Circuit Evaluation (&&, ||), Hardware Null Guards & Bitwise vs Logical Gotchas
Executive Summary: Exploring logical operators (&&, ||, !). We analyze Short-Circuit Evaluation, demonstrate how short-circuiting provides safe null pointer guards before hardware MMIO register dereferencing, and highlight dangerous bugs caused by confusing logical (&&) with bitwise (&) operators.
💻 1. Annotated Source Code
#include <iostream> using namespace std; int main() { bool isRaining = false; bool isWarm = false; cout << boolalpha; cout << "isRaining AND isWarm: " << (isRaining && isWarm) << endl; cout << "isRaining OR isWarm: " << (isRaining || isWarm) << endl; cout << "NOT isRaining: " << (!isRaining) << endl; return 0; }
📐 2. Architecture & UML Class Model
<<compilation-unit>>
LogicEngine
Short-Circuit Optimizer
Attributes / Data Members
-isRaining : bool
-isWarm : bool
Operations / Methods
+evaluateAnd(condA: bool, condB: bool) : bool
+evaluateOr(condA: bool, condB: bool) : bool
+evaluateNot(cond: bool) : bool
📚 3. Core C++ Concepts Deep-Dive
1. Short-Circuit Evaluation
A && B: IfAisfalse,Bis never evaluated.A || B: IfAistrue,Bis never evaluated.
2. Null Pointer Guard Idiom
Thanks to short-circuiting, if (ptr != nullptr && ptr->status == OK) is completely safe; if ptr is null, the second expression is never executed, preventing null pointer dereference crashes.
⚡ 4. Embedded Systems & Hardware Reality
1. Dangerous Bug: & vs &&
Using bitwise & instead of logical && evaluates both sides unconditionally without short-circuiting. If applied to a null guard, it will crash the CPU with a HardFault.
💡 5. Production-Ready Embedded Refactoring
Short-circuit hardware peripheral guard:
💡 Production-Ready Refactor
#include <cstdint> struct UartHardware { volatile uint32_t SR; volatile uint32_t DR; }; // Safe: If dev is null, dev->SR is never accessed bool isUartReady(const UartHardware* dev) noexcept { return (dev != nullptr) && ((dev->SR & (1UL << 7)) != 0); }
📝 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. How does 'Short-Circuit Evaluation' protect the expression 'if (ptr != nullptr && ptr->val > 0)' from crashing when ptr is null?
Detailed Explanation:
In
&& expressions, if the left operand is false, the right operand is guaranteed not to execute.
Q2. What happens if a developer mistakenly writes 'if (ptr != nullptr & ptr->val > 0)' with a single bitwise '&' when ptr is null?
Detailed Explanation:
Bitwise
& is an arithmetic operator that does not short-circuit; both operands evaluate, causing a null pointer dereference.
Q3. What is the result of '!true' in C++?
Detailed Explanation:
The logical NOT operator (
!) inverts boolean truth, turning true into false.
Q4. In the expression 'if (is_admin || check_database())', when will 'check_database()' be executed?
Detailed Explanation:
In
|| expressions, if the left operand is true, the overall result is already known to be true, so the right operand is skipped.