Rung 2 — libprep: A Reusable C Container Library¶
Headline. A small, tested, sanitizer-clean C library that ships five data structures with a coherent API — the first artifact where you are designing, not just coding.
Month target. M3 (September 2026). Publish by the last day of M3.
What You Build¶
Repo name: libprep (the name is a wink — these are the containers you keep re-implementing in studies). Header-optional layout so the library can be used as a single-header drop-in OR built as a static archive.
Five data structures, each in its own translation unit:
iv_vec— dynamic array ofvoid*(or a type-generic macro variant). Push, pop, insert, remove, reserve, shrink-to-fit. Amortized O(1) push.iv_str— growable string builder.append,appendf(printf-style),cstr,len,clear. Guarantees NUL termination.iv_map— hashmap using open addressing with Robin Hood or linear probing. String keys,void*values.put,get,del,iter. Load-factor bounded resize.iv_heap— binary heap. Configurable min or max via comparator function pointer.push,pop,peek,heapifyfrom array.iv_deque— double-ended queue backed by a ring buffer with power-of-two capacity.push_front,push_back,pop_front,pop_back.
Required infrastructure:
Test suite: one
.cper data structure, using a tiny assertion macro (roll your ownIV_ASSERTin ~20 LOC). No external test framework — dogfooding your ability to write test infrastructure is part of the rung.Coverage:
gcov+lcovproducing an HTML report, checked intodocs/coverage/or hosted on GitHub Pages. Target ≥ 90% line coverage.Sanitizer runs: ASan and UBSan clean on every push via GitHub Actions.
Fuzzing (optional but recommended): one
libFuzzerorAFL++harness foriv_map— 5000 iterations run in CI as a smoke test.README with a runnable example for each of the five containers, plus an “ownership rules” section that states, in one paragraph per container, who owns the memory and when.
Target size: <phone_number_or_numberic_id_or_random_id_4>-2500 LOC of C, one README.md, five example programs in examples/.
Why This Rung, Why Now¶
M2 has taught you the language deep-dive: strict aliasing, undefined behavior, restrict, const correctness, translation units, linkage. Rung 2 forces you to use that knowledge to make interface decisions. Every container demands an answer to questions you never had to ask in Python: who owns the memory? What happens on failure — return NULL or abort? Are elements copied by value or referenced? Is iteration invalidated by mutation? These are not exotic questions — they are the exact questions the maintainer of any real C library gets asked in code review.
You ship in M3 because Rung 3 (NeetCode-75 in C) is much easier if you already have your own iv_map and iv_deque to lean on. Rung 2 becomes infrastructure for Rung 3.
Acceptance Criteria¶
5 data structures, each with a public header, an implementation file, and a test file
≥ 90% line coverage measured by
gcov/lcov, report visible in repoZero ASan and zero UBSan errors under the full test suite
README has a copy-pasteable ≤ 15-line example for each container
Ownership semantics documented explicitly for every container (who frees what, when)
Every public function has a doc comment stating: pre-conditions, post-conditions, complexity, failure mode
Posted to
r/C_Programmingwith title “libprep — my first C library, feedback welcome” and you engaged with at least 5 commentsTagged v0.1.0 release with a CHANGELOG entry
Where to Publish¶
GitHub: pinned on profile. Add topics:
c,data-structures,c99,library.Reddit:
r/C_Programmingfor a feedback thread. Do NOT post tor/programmingyet — it’s a small-library rung, not a HN piece.Hacker News: skip. Rung 5 and Rung 6 are your HN candidates. Do not burn HN attention on a first library.
Lobsters: optional; only if you have an invite.
Your GitHub profile README: add a “Portfolio” section and link this repo with the one-line pitch.
Signal to Recruiter / Employer¶
“This person can design and ship a small library. They think about API discipline, ownership discipline, and testing discipline. They are not merely a person who can compile C — they are a person who could contribute to a C codebase without breaking it.”
Rung 2 also makes you legible to hobbyist C communities. If a maintainer on r/C_Programming gives you a piece of feedback and you incorporate it in a follow-up commit, you have just performed a rehearsal of the OSS PR loop that Rung 7 will demand.
Common Failure Modes¶
Generic macros that no one can read. You try to write a template-like
#define VEC(T)and end up with 400-line macro expansions that segfault under ASan. Detection: ifgcc -Eoutput for a test file exceeds 3000 lines, you overreached — back off tovoid*with typedef aliases.Silent allocation failure.
iv_vec_pushcallsrealloc,reallocreturns NULL, and you crash 40 lines later at a use-site. Detection: grep the code for everymalloc/realloc/calloc— each must have an explicit NULL check with a documented behavior.Iterator invalidation left undocumented. Mutating during iteration is UB in your library but you never say so. Detection: every
iterfunction must have a comment starting “Invalidated by: …”.Coverage number faked. You count lines by running the test binary once and calling it done. Detection:
gcovoutput shows uncovered branches in error paths — those branches must be exercised (via a fault-injection macro if needed).
Estimated Hours¶
iv_vec: 6hiv_str: 4hiv_map: 12h (this is the hard one; open addressing + resize + iter is genuinely tricky)iv_heap: 5hiv_deque: 5hTest suite + coverage tooling: 8h
Sanitizer + CI wiring: 4h
README + examples + polish: 8h
Reddit feedback iteration: 4h
Total: ~55 hours across M2-M3. Two months at ~28h/month is comfortable at 10-12h/week.
Prior-Art / Inspirations to Study First¶
nothings/stb(single-header libs by Sean Barrett) — readstb_ds.hline by line. It is the reference for a small, elegant C container header.troydhanson/uthash— the hashmap-as-macros approach. Even if you don’t copy it, read the docs for the ownership discussion.redis/dict.cin the Redis source — industrial-strength hashmap in production. Skim it, don’t copy it, notice how much of it is comments and invariants.
Return to README.md · Previous: 01_rung_1_toolchain_journal.md · Next: 03_rung_3_neetcode75_in_c.md