Hacker News new | ask | show | jobs
by fghvbnvbnfe 3342 days ago
Ada addresses memory issues in a couple ways. In a general sense, the language is designed to prevent the need for explicit allocations and pointers as much as possible. The runtime uses a secondary stack to return dynamically-sized objects from functions. The low level parameter passing details are also compiler-controlled. The programmer specifies how an argument is used (input, output, or both) and the compiler deals with how to accomplish that. There are some other features (mostly related to types and bounds) that all combine to generally reduce the need for explicit memory management.

Once you do get to explicit memory management, Ada does a number of things. I'm going to a list here just for my own sanity.

First, all deallocations are essentially marked unsafe. You use Unchecked_Deallocation() to free memory.

More importantly, it provides memory pools, and subpools. Each pointer type can be associated with a pool (or subpool). Once the pool goes out of scope, all memory is freed. You can use this to avoid explicit deallocations yourself. Pools also control allocations and deallocations, and there exist Debug pools that can help ensure memory is accessed correctly.

Ada also requires that stack-based objects be declared as "aliased" before you may make a pointer to them, so it's always clear where there might be trouble.

Finally (I think), Ada has a concept of accessibility levels. Essentially a pointer cannot point to an object that is more deeply scoped than itself. This isn't the perfection of the Rust borrow checker, but it does quite a bit.

As for C FFI, Ada does that quite well. It's got a package in the standard library with C interface types, and aspects for marking things for C FFI.