name: zireael-code-style description: Write readable C with proper comments, named constants, and consistent style per CODE_STANDARDS.md. metadata: short-description: Code style + comments + constants
When to use
Use this skill when:
- writing new C code
- reviewing code for style compliance
- adding comments to existing code
- extracting magic numbers to constants
- normalizing coding patterns
- simplifying dense bitwise/mask/ternary expressions
Source of truth
docs/CODE_STANDARDS.md— naming, comments, function size, ownership docsdocs/SAFETY_RULESET.md— safety and determinism rulesdocs/LIBC_POLICY.md— allowed/forbidden libc functions
File header comments (required)
Every .c/.h file MUST start with:
/*
path/to/file.c — Brief description (one line).
Why: Explain the purpose and key design decisions.
*/
Function-level comments (required for non-trivial functions)
MUST have a function-level comment when:
- Public API function (appears in header, called by other modules)
- Function is > 20 lines with non-obvious behavior
- Function has subtle behavior (coalescing, tie-breaking, capability downgrading)
- Internal helper called from multiple places
Function comment format (1-3 lines):
/* Map 24-bit RGB to nearest xterm 256-color index, comparing both
* the 6x6x6 color cube and grayscale ramp to find the best match. */
static uint8_t zr_rgb_to_xterm256(uint32_t rgb) {
DO NOT need function-level comment:
- Trivial one-liners (e.g.,
zr_rgb_r(),zr_style_default()) - Simple getters/setters with self-explanatory names
- Static helpers < 10 lines with obvious intent
Inside-function comments (strategic)
Add comments inside functions for:
- Complex algorithms (brief overview, not line-by-line)
- Decision rationale (why this ranking/tie-break exists, not field glossary)
- State machines (what each state variable tracks)
- Spec-derived logic (reference the spec, e.g., "UAX #29 GB11")
- Non-obvious defensive patterns (e.g., "accepts NULL for cleanup convenience")
Do NOT add comments that:
- Restate the code (
/* increment i */ i++) - Explain obvious stdlib usage
- Pad length without adding value
Strategic comment types
ASCII diagrams for data structures
/*
* Ring buffer layout:
*
* Case 1: tail >= head
* [....head=====tail....]
*
* Case 2: tail < head (wrapped)
* [====tail......head====]
*/
Section markers in long functions
/* --- Validate inputs --- */
...
/* --- Process data --- */
...
/* --- Write outputs --- */
Format reminders for bit layouts
/* RGB stored as 0x00RRGGBB */
Invariant protection
/* Ensures offset + size doesn't overflow before pointer creation */
Expression readability (required)
When expressions combine shifts, masks, chained ternaries, or multiple fallbacks:
- split into named intermediate values
- keep each line to one conceptual operation
- extract repeated encoding/offset math into small helpers
/* AVOID */
g.bytes[0] = (uint8_t)(ZR_UTF8_3BYTE_LEAD | ((cp >> 12u) & ZR_UTF8_3BYTE_MASK));
/* PREFERRED */
const uint8_t cp_top4 = zr_utf8_bits(cp, 12u, ZR_UTF8_3BYTE_MASK);
g.bytes[0] = zr_utf8_make_lead(ZR_UTF8_3BYTE_LEAD, cp_top4);
Named constants (required)
Extract magic numbers to named constants:
/* BAD */
if (align > 4096u) return false;
/* GOOD */
#define ZR_ARENA_MAX_ALIGN 4096u
if (align > ZR_ARENA_MAX_ALIGN) return false;
Group related constants with section comments:
/* --- SGR (Select Graphic Rendition) codes --- */
#define ZR_SGR_RESET 0u
#define ZR_SGR_BOLD 1u
#define ZR_SGR_ITALIC 3u
NULL check style
Use !ptr consistently:
/* GOOD */
if (!ptr) return ZR_ERR_INVALID_ARGUMENT;
/* AVOID */
if (ptr == NULL) return ZR_ERR_INVALID_ARGUMENT;
Function size
- Target: 20-40 lines
- Maximum: 50 lines
- If larger: split into helpers with clear names
Naming conventions
| Type | Convention | Example |
|---|---|---|
| Functions | module_action_noun() |
arena_alloc_aligned() |
| Variables | snake_case descriptive |
bytes_remaining |
| Constants | ZR_MODULE_NAME |
ZR_DL_MAGIC |
| Types | zr_name_t |
zr_arena_t |
Review checklist
Before finalizing code:
- File has header comment with "Why"
- Non-trivial functions (> 20 lines or subtle behavior) have function-level comment
- Public API functions have function-level comment
- Complex logic inside functions has strategic comments (diagrams, state tracking, invariants)
- Complex-path comments explain rationale/tradeoffs, not only field semantics
- Dense shift/mask/ternary expressions are split into named intermediates or helpers
- Magic numbers extracted to named constants
- NULL checks use
!ptrstyle - Functions under 50 lines
- No comments that restate code