C3 solved memory lifetimes with scopes
Title and framing
- Many commenters find the title (“solved memory lifetimes”, “forget borrow checkers”) misleading or click‑baity.
- Strong view that the post is about ergonomic temporary allocation in a C‑like language, not about replacing Rust’s borrow checker or solving memory safety.
- Some see the borrow‑checker reference as technically incorrect and rhetorically antagonistic; others call it an unfortunate, now‑regretted title choice.
What @pool / Temp allocator actually provides
@poolwraps a lexical scope in a “temp allocator” / arena: allocations inside are bulk‑freed when leaving the scope.- There’s a default temp allocator for
main, and library functions often have both allocator‑taking andt*(temp‑allocating) variants. - Benefits emphasized: fewer leaks for temporary data, grouped allocations for locality, cheap bulk free, and integration into the standard library.
Safety and borrow‑checking concerns
- Several commenters stress that this does not prevent use‑after‑free or aliasing bugs as a borrow checker does.
- It is possible to return pointers to temp‑allocated memory and then use them after the pool is gone; behavior ranges from memory being overwritten/poisoned to crashes or ASAN reports, depending on mode and platform.
- In “safe mode” the allocator may scribble over freed memory, but this is runtime detection, not static prevention, and not guaranteed in all builds.
- Critics argue you therefore cannot claim memory safety or “solved lifetimes” in the Rust sense.
Comparison to RAII, arenas, and older techniques
- Many note this is essentially region/arena allocation tied to lexical scopes, a long‑known idea (obstacks, NSAutoreleasePool, Ada pools, C++ arenas).
- In C++ you can get similar behavior with RAII plus arena allocators; in Rust via crates like bumpalo.
- Proponents reply that C3 deliberately avoids RAII/ownership semantics to stay close to C: data is “inert”, no constructors/destructors; other resources are handled via
defer. - Some see the main real value as: making temp arenas the idiomatic, built‑in pattern in a C‑like language without GC or RAII.
Use cases and limitations
- Works well for clearly scoped temporaries (e.g.,
foo(bar())without leaks) and per‑frame or per‑request arenas. - Commenters highlight missing coverage for common non‑lexical patterns: cross‑thread queues, long‑lived resources, complex game/resource managers.
- Without restrictions on moving pointers between pools or alias analysis, escaping references remain a problem.
Rust compile times and misconceptions
- Thread digresses into Rust: several clarify that borrow checking is not the main source of Rust’s slow compile times; generics/monomorphization, LLVM optimization, and proc macros dominate.
- Some tutorials and the blog’s wording are criticized for reinforcing the misconception that lifetimes/borrow checking inherently cause slow compilation.
Contracts and static checking in C3
- C3 has contracts, but there is no language‑level guarantee they are statically enforced; some violations are even categorized as undefined behavior outside “safe” modes.
- Commenters find “might be statically checked” contracts dangerous and closer to linting than to sound static guarantees.