1---2name: c99-guide3description: Use when editing or reviewing general-purpose C99: libraries, CLI tools, system code without strong opinions on memory ownership or layout. Triggers on `.c`/`.h` files and prompts about C99 idioms, designated initializers, fixed-width types, const-correctness, malloc/free patterns, inline functions, value-oriented APIs, sanitizers, or error returns, even when the user doesn't say 'C'.4---56# C99 Coding Guidelines78## Essentials910- **Memory management** - Free all heap allocations, avoid leaks, see [references/memory-management.md](references/memory-management.md)11- **Modern C99** - Use `const`, designated initializers (ZII), small functions, see [references/designated-initializers.md](references/designated-initializers.md), [references/const-correctness.md](references/const-correctness.md)12- **Fixed-width types** - Name widths with `<stdint.h>` for sized/serialized data; `size_t` for counts and indices, see [references/fixed-width-types.md](references/fixed-width-types.md)13- **Type safety** - Favor `inline` functions over macros where practical, see [references/inline-functions.md](references/inline-functions.md)14- **Quality** - Pin strict C99, treat warnings as errors, keep an ASan/UBSan debug build, run static analysis, see [references/build-and-warnings.md](references/build-and-warnings.md)1516## Best practices1718- **Error handling** - Use return codes, check all fallible operations, see [references/error-handling.md](references/error-handling.md)19- **Value-oriented APIs** - Return small results by value; reserve out-params for large or multiple results, see [references/value-types.md](references/value-types.md)20- **Strings** - Borrow length-carrying views, write through bounded builders over caller memory, not `strlen`/`strcat`/`strtok` rescans, see [references/string-views.md](references/string-views.md)21- **Input validation** - Check bounds, NULL pointers, division by zero22- **Readability** - Small functions, clear naming, comments for non-obvious logic23- **Paradigm** - Functional style (pure functions, explicit context) → **fp-guide**; object/data modeling → **oop-guide**2425## Gotchas2627- Signed integer overflow is undefined behavior, even `INT_MAX + 1` lets the compiler eliminate "impossible" code paths28- Strict aliasing means casting `int*` to `float*` is UB unless via `union` or `memcpy`: silently miscompiled at higher optimization levels29- `malloc` returns memory that's max-aligned; custom arenas must preserve alignment for `_Bool`/`double`/SIMD types30- Designated initializers (`.field = x`) zero-fill unmentioned members: a missing field becomes silent zero, not a compile error31- `long` is 32-bit on Windows and 64-bit on most 64-bit Unix targets: a struct of `int`/`long` serializes and hashes differently per platform; use `<stdint.h>` exact-width types for any stored or shared data32- Comparing a signed `int` against an unsigned `size_t` converts the `int`: a negative value becomes a huge `size_t` and the bounds check passes; keep counts/indices in `size_t` end to end33- Return-by-value is for _small_ PODs; returning a large struct just copies it: large or caller-owned results still take a pointer34- `-std=c99` usually still means the GNU dialect: set `C_EXTENSIONS OFF` for true ISO C99, then `#define _XOPEN_SOURCE 700` or POSIX calls (`readlink`, `strnlen`, `ssize_t`) become implicit-declaration errors35- `-Wextra`'s `-Wmissing-field-initializers`/`-Wmissing-braces` fire on intentional zero-init: suppress those two, keep the rest of `-Werror`3637## Progressive disclosure3839- Read [references/build-and-warnings.md](references/build-and-warnings.md) - Load when configuring the C standard, feature-test macros, warning flags, or sanitizers40- Read [references/fixed-width-types.md](references/fixed-width-types.md) - Load when choosing integer types for struct fields, serialized data, counts, or indices41- Read [references/string-views.md](references/string-views.md) - Load when handling strings without repeated terminator scans or hidden allocations42- Read [references/value-types.md](references/value-types.md) - Load when designing function signatures: returning results by value vs. out-parameters43- Read [references/memory-management.md](references/memory-management.md) - Load when allocating memory or managing resource lifetimes44- Read [references/designated-initializers.md](references/designated-initializers.md) - Load when initializing structs or arrays with specific values45- Read [references/inline-functions.md](references/inline-functions.md) - Load when replacing macros or writing small utility functions46- Read [references/compound-literals.md](references/compound-literals.md) - Load when creating temporary values without named variables47- Read [references/const-correctness.md](references/const-correctness.md) - Load when marking immutable data or understanding pointer const48- Read [references/error-handling.md](references/error-handling.md) - Load when implementing error codes or handling failures