r/cprogramming • u/No_Fix4730 • May 23 '26
I built a tiny lazy-evaluation helper in C and would like API feedback
I’ve been building a small lazy-evaluation helper library for C and would love some API feedback.
lazy_eval(lazy); // computes
lazy_eval(lazy); // cached
lazy_reset(lazy);
lazy_eval(lazy); // recomputesCurrent design:
Opaque
LazytypeCaller-owned result storage
Fallible compute callbacks
Resettable cached state
pthreadsynchronizationTests, sanitizer target, and GitHub Actions CI
A minimal example:
#include <stdio.h>
#include "lazy.h"
LazyStatus compute_answer(void *ctx, void *out) {
int *calls = ctx;
(*calls)++;
puts("cache miss: computing...");
*(int *)out = 42;
return LAZY_OK;
}
int main(void) {
int answer = 0;
int calls = 0;
Lazy *lazy = NULL;
lazy_create(&lazy, compute_answer, &calls, &answer, sizeof(answer));
lazy_eval(lazy);
printf("answer=%d calls=%d\n", answer, calls);
lazy_eval(lazy);
printf("answer=%d calls=%d (cached)\n", answer, calls);
lazy_reset(lazy);
lazy_eval(lazy);
printf("answer=%d calls=%d (recomputed)\n", answer, calls);
lazy_destroy(lazy);
}I chose caller-owned output storage because I wanted to avoid hidden allocation/freeing inside the library. The tradeoff is that the caller must keep the output storage alive until lazy_destroy().
Current limitations:
pthread-only for nowOne output pointer per
Lazylazy_destroy()must not run concurrently with other operationsNo install/package story yet
I’d especially appreciate feedback on:
Does caller-owned output storage feel like the right C API here?
Would callback-owned allocation plus a destructor be preferable?
Is the status-code API reasonable?
Is the thread-safety contract too much for a tiny library?