Assume modern GCC, C99+, unless evidence says otherwise. Prefer data-oriented design.
BIT/ARRAY_LEN; avoid macros containing logic and conditional-compilation feature gates.BIT macros instead).stdint.h) for I/O-bound data (wire formats, packed structs); plain int/size_t remain fine for loop counters and other transient values._Static_assert for compile-time invariants; GCC supports it as an extension even before C11.(void).if (data), if (!data)) rather than comparing against NULL or 0.goto EXIT a single cleanup block rather than duplicating cleanup at each early return:
int foo(void) {
int ret = -1;
resource_t *r = acquire();
if (!r) goto EXIT;
if (do_work(r) != 0) goto EXIT;
ret = 0;
EXIT:
release(r);
return ret;
}
.c over .hstatic over globalstatic function names with _const wherever possible{ }) as possible.c)Order: includes -> preprocessor -> typedefs -> extern vars -> static vars -> static functions -> public functions.
.h)#ifndef/#define (not #pragma once), named <FILENAME>__ (e.g. event_db.h -> EVENT_DB__):
```c
#ifndef FILENAME__
#define FILENAME__// …
#endif // FILENAME__
## Structs
- Always `typedef`; prefer anonymous.
- Add `packed` to any struct that is serialized/deserialized.
- Initialize, set, and copy safely:
```c
foo_t foo = { /* optional initial values */ }; // initialize (designated initializer)
foo = (foo_t){ /* ... */ }; // set (compound literal)
foo = foo_b; // copy
typedef; prefer anonymous.<PREFIX>_COUNT.#define for any group of related integer constants; reserve const/#define for sparse or non-integer values.static const struct { const char *name; bool data_required; } FOO_DATA[] = { [FOO_A] = { .name = “A”, .data_required = true, }, [FOO_B] = { .name = “B”, .data_required = false, }, }; _Static_assert(ARRAY_LEN(FOO_DATA) == FOO_COUNT, “FOO_DATA/FOO_COUNT mismatch”); ```
.clang-format file codifying stylistic preferences. Use it to format large sections of newly written code before reporting done.const, to invoke casting implicitly instead./* */ comment; // stays fine inline and trailing.{ opens on the designator’s line, one field per line, trailing comma (see FOO_DATA above).