← Back to context

Comment by sirwhinesalot

6 months ago

The advantage is that the allocations are grouped: they're allocated in the same memory region (good memory locality) and freed in bulk. The tradeoff is needing to explicitly create these scopes and not being able to have custom deallocation logic like you can in a destructor.

(This doesn't seem to have anything to do with borrow checking though, which is a memory safety feature not a memory management feature. Rust manages memory with affine types which is a completely separate thing, you could write an entire program without a single reference if you really wanted to)

You can also do those things in an RAII language with an arena library. Is the complaint just that it's too syntactically verbose?

  • I am also struggling to see the difference between this and language-level support for an arena allocator with RAII.

    • You can certainly do it with RAII. However, what if a language lacks RAII because it prioritizes explicit code execution? Or simply want to retain simple C semantics?

      Because that is the context. It is the constraint that C3, C, Odin, Zig etc maintains, where RAII is out of the question.

      5 replies →

  • I think the point is that it is the blessed/default way of doing things, rather than opt-in, as in C++ or Rust.

    Rust doesn't even have a good allocator interface yet, so libraries like bumpalo have a parallel implementation of some stdlib types.

  • It seems like exactly the same verbosity as what you'd do with a custom allocator.

    I think the only real grace is you don't have to pass around the allocator. But then you run into the issue where now anyone allocating needs to know about the lifetimes of the pool of the caller. If A -> B (pool) -> C and the returned allocation of C ends up in A, now you potentially have a pointer to freed memory.

    Sending around the explicit allocator would allow C to choose when it should allocate globally and when it should allocate on the pool sent in.