summaryrefslogtreecommitdiff
path: root/doc/CONTRIBUTING.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/CONTRIBUTING.md')
-rw-r--r--doc/CONTRIBUTING.md76
1 files changed, 76 insertions, 0 deletions
diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md
index ae8c35a..d7ea448 100644
--- a/doc/CONTRIBUTING.md
+++ b/doc/CONTRIBUTING.md
@@ -340,6 +340,82 @@ For tests that only need synth or tracker (not both), you can still call `synth_
These are performance-critical APIs and should be called directly, not wrapped by AudioEngine.
+### Fatal Error Checking
+
+The project uses fatal error checking macros that can be stripped for final builds. These are defined in `src/util/fatal_error.h`.
+
+**When to use fatal error checks:**
+
+Use fatal error checking for conditions that indicate programming errors or corrupt state that cannot be recovered from:
+- Bounds checking (array/buffer overflows)
+- Null pointer checks
+- Invariant violations
+- Invalid state transitions
+
+**DO NOT use for:**
+- Expected runtime errors (file not found, network errors)
+- Recoverable conditions
+- Input validation (use return codes instead)
+
+**Macro Reference:**
+
+```cpp
+#include "util/fatal_error.h"
+
+// Conditional check (most common - 90% of cases)
+FATAL_CHECK(write_pos >= capacity,
+ "write_pos out of bounds: %d >= %d\n",
+ write_pos, capacity);
+
+// Unconditional error (should-never-happen)
+FATAL_ERROR("Invalid state: %d\n", state);
+
+// Unreachable code marker (switch defaults)
+switch (type) {
+ case TYPE_A: return handle_a();
+ case TYPE_B: return handle_b();
+ default: FATAL_UNREACHABLE();
+}
+
+// Assertion-style (documenting invariants)
+FATAL_ASSERT(buffer != nullptr);
+FATAL_ASSERT(count > 0 && count < MAX_COUNT);
+
+// Complex validation blocks
+FATAL_CODE_BEGIN
+ static int callback_depth = 0;
+ ++callback_depth;
+ if (callback_depth > 1) {
+ FATAL_ERROR("Callback re-entered! depth=%d", callback_depth);
+ }
+FATAL_CODE_END
+```
+
+**Build modes:**
+- **Debug/STRIP_ALL**: All checks enabled, full error messages with file:line info
+- **FINAL_STRIP**: All checks compiled out (zero runtime cost, ~500-600 bytes saved)
+
+**Testing requirement:**
+
+Before committing code with fatal error checks, verify both modes compile:
+
+```bash
+# Normal build (checks enabled)
+cmake -S . -B build
+cmake --build build && cd build && ctest
+
+# FINAL_STRIP build (checks stripped)
+cmake -S . -B build_final -DDEMO_FINAL_STRIP=ON
+cmake --build build_final
+```
+
+Or use the convenience script:
+```bash
+./scripts/build_final.sh
+```
+
+**Important:** Never use `FATAL_CHECK` for conditions that can legitimately occur during normal operation. These are for programming errors only.
+
### Script Maintenance After Hierarchy Changes
After any major source hierarchy change (moving, renaming, or reorganizing files), you **must** review and update all scripts in the `scripts/` directory to ensure they remain functional.