diff options
Diffstat (limited to 'doc/CONTRIBUTING.md')
| -rw-r--r-- | doc/CONTRIBUTING.md | 76 |
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. |
