The safety default: allocating functions return ARENA_PTR handles (packed arena_id + offset integers), not raw pointers. A dangling pointer at a function return boundary is unconstructable by default. Cross-scope lifetime extension is explicit — you enter the target arena via SCOPE(ptr) before allocating, which routes the object into the outer arena without transferring ownership.
Benchmarks (no optimization flags): 1M-node tree cleanup drops from 31ms to 1ms (~30×). There's a real regression in tight inner loops (~0.76×) because DEREF can't hoist the base pointer the way a compiler would — the spec documents this honestly.
This is a C macro-based proof-of-concept for a memory model I'm targeting in a compiled language. The interesting question isn't the C implementation — it's whether scope-structured arena routing is a sound replacement for GC and borrow checking across the class of programs that matter.
Repo: https://github.com/hollow-arena/ariandel — SPEC.md has the full model including concurrency semantics and the comparison to Tofte & Talpin region-based memory.