|
I kept rewriting the same low-level patterns in C — arenas, memory management, error handling, vectors, parsing, file I/O, iteration utilities — and existing libraries either hide allocation, impose frameworks, or lack consistency. So I built Canon-C, a small, composable set of explicit C modules that: Treat C as an execution backend, not a semantic authority Add meaning through libraries, not syntax Make intent visible directly in the API: ownership, lifetime, and failure handling are explicit Modules are organized by semantic layers: core/ — memory, lifetime, scope, primitives semantics/ — Option, Result, error handling data/ — vectors, queues, stacks, string builders algo/ — map, filter, fold, sort, search util/ — safe string ops, file I/O, logging, timing Design highlights: Header-only No runtime or global state No hidden allocation (except in clearly marked convenience layers) Fully explicit behavior I’d love feedback from anyone doing systems programming, embedded C, or serious C projects, especially on macro-heavy vs. modular design, semantic clarity, and practical usage. |
>FILE* f = fopen(path, "rb");
>...
>if (fseek(f, 0, SEEK_END) != 0) return option_charp_none();
>long len = ftell(f);
does ISO C guarantee this'll work these days? How come there's no fread+realloc fallback?