mirror of
https://github.com/rsyslog/rsyslog.git
synced 2026-03-19 14:09:30 +01:00
Standardizing how we handle "impossible" states to help automated tools detect bugs while keeping production code simple and stable. This modernization step aids maintainability and AI-assisted reviews. BEFORE: No formalized guidance for "impossible" path handling. AFTER: Mandatory assertions with optional defensive fallbacks. Introduced a formalized hybrid pattern for defensive programming. The new guidance mandates the use of assert() for all invariants to allow Static Analyzers and AI agents to reason about code state correctly. It also recommends an optional defensive if fallback to prevent production crashes, except where recovery logic would be excessively complex. Updated the top-level AGENTS.md with a brief instruction and added a detailed practice document to the coding_practices catalog. Prohibited use of __builtin_unreachable() to prevent undefined behavior in release builds. AI-Agent: Antigravity
35 lines
1.3 KiB
ReStructuredText
35 lines
1.3 KiB
ReStructuredText
.. _defensive-coding-and-assertions:
|
|
|
|
Defensive Coding and Assertions
|
|
===============================
|
|
|
|
**Classification**: Pattern
|
|
|
|
**Context**: Handling "impossible" states or logic paths that should theoretically never be reached.
|
|
|
|
**Why it matters**:
|
|
Rsyslog prioritizes production stability. We use Static Analysis (SA) and CI to detect bugs. ``assert()`` tells analyzers/AI that a state is invalid. Defensive checks protect production from crashes if the "impossible" happens.
|
|
|
|
**Steps**:
|
|
|
|
1. **Mandatory Assertion**: Always use ``assert()`` to define the invariant. This informs SA tools and AI assistants that this state is invalid.
|
|
2. **Optional Defensive Fallback**: Follow the assert with an ``if`` check to handle the failure gracefully. This is recommended but optional if the fallback handler would be excessively complex or introduce more risk than it solves.
|
|
3. **No UB**: Never use ``__builtin_unreachable()``.
|
|
4. **Order**: Place the ``assert()`` before the defensive check.
|
|
|
|
**Example**:
|
|
|
|
.. code-block:: c
|
|
|
|
/* 1. Inform SA/AI */
|
|
assert(pPtr != NULL);
|
|
|
|
/* 2. Defensive check (optional if complex) */
|
|
if (pPtr == NULL) {
|
|
LogMsg(0, NO_ERRCODE, LOG_ERR, "logic error: pPtr is NULL");
|
|
return;
|
|
}
|
|
|
|
/* 3. Logic */
|
|
do_something(pPtr);
|