Earlier quoted context omitted.
> had difficulty being adopted more broadly Most applications don’t need to bother the user with things like how much memory they think will be needed upfront. They just allocate how much and when necessary. Most applications today are probably servers that change all the time. You would not know upfront how much memory you’d need as that would keep changing on every release! Static allocation may work in a few domai…
That's just saying "we push our memory problems up the stack so our clients / users need to deal with that". The reason this works is because human users in particular have become accustomed to software being buggy and failing often.
Static Allocation with Zig
71–80 of 112 posts
Re: Static Allocation with Zig
#72> All memory must be statically allocated at startup. But why? If you do that you are just taking memory away from other processes. Is there any significant speed improvement over just dynamic allocation?
1. On modern OSes, you probably aren't "taking it away from other processes" until you actually use it. Statically allocated but untouched memory is probably just an entry in a page table somewhere. 2. Speed improvement? No. The improvement is in your ability to reason about memory usage, and about time usage. Dynamic allocations add a very much non-deterministic amount of time to whatever you're doing.
Re: Static Allocation with Zig
#73Earlier quoted context omitted.
I’m confused. How is a program that uses static allocation not Turing complete?
A Turing machine has an unlimited tape. You can’t emulate it with a fixed amount of memory. It’s mostly a theoretical issue, though, because all real computer systems have limits. It’s just that in languages that assume unlimited memory, the limits aren’t written down. It’s not “part of the language.”
Re: Static Allocation with Zig
#74Re: Static Allocation with Zig
#75Earlier quoted context omitted.
Those guidelines are quite clear that they're written specifically in the context of the C programming language, and may not make sense in other contexts: "For fairly pragmatic reasons, then, our coding rules primarily target C and attempt to optimize our ability to more thoroughly check the reliability of critical applications written in C." A version of this document targeting, say, Ada would look quite different.
The JPL C rules are quite old, but avoiding dynamic allocation outside initialization is am considered best practice for spaceflight software regardless of language. Here's the recommendation from NASA's language-agnostic cFS: 4.2.4 Consolidate Resource Allocations It is generally recommended to consolidate resource allocations to the application initialization function(s). Allocations and setup of resources such as…
The rules are written with the historical context of C making it too easy to leak heap-allocated memory. In the safety-critical Rust code that I've worked on, we tend not to dynamically allocate due to the usual constraints, and we're well aware of the "thou shalt not allocate" rules in the scripture, but we've already gotten clearance from the relevant certification authorities that Rust is exempt from the restriction against dynamic allocation specifically because of its ownership system.
Re: Static Allocation with Zig
#76Personally I believe static allocation has pretty huge consequences for theoretical computer science. It’s the only kind of program that can be actually reasoned about. Also, not exactly Turing complete in classic sense. Makes my little finitist heart get warm and fuzzy.
No. That is one restriction that allows you to theoretically escape the halting problem, but not the only one. Total functional programming languages for example do it by restricting recursion to a weaker form.
Also, more generally, we can reason about plenty of programs written in entirely Turing complete languages/styles. People keep mistaking the halting problem as saying that we can never successfully do termination analysis on any program. We can, on many practical programs, including ones that do dynamic allocations.
Conversely, there are programs that use only a statically bounded amount of memory for which this analysis is entirely out of reach. For example, you can write one that checks the Collatz conjecture for the first 2^1000 integers that only needs about a page of memory.
Re: Static Allocation with Zig
#77> All memory must be statically allocated at startup. No memory may be dynamically allocated (or freed and reallocated) after initialization. This avoids unpredictable behavior that can significantly affect performance, and avoids use-after-free. As a second-order effect, it is our experience that this also makes for more efficient, simpler designs that are more performant and easier to maintain and reason about, com…
Static allocation has been around for a long time but few people consider it even in contexts where it makes a lot of sense. I’ve designed a few database engines that used pure static allocation and developers often chafe at this model because it seems easier to delegate allocation (which really just obscures the complexity). Allocation aside, many optimizations require knowing precisely how close to instantaneous re…
NB: I was just a newbie back then, so any older grey beards, please feel free to correct me. But I distinctly remember supporting commercial databases as being one of the justifications for overcommit, despite overcommit not being typical in the environments originally running those DBs, AFAIU.
[1] Note that AFAIU the BSDs had overcommit, too, but just for fork + CoW. Though these days FreeBSD at least has overcommit more similar to Linux. Solaris actually does strict accounting even for fork, and I assume that was true back in the 90s. Did any commercial Unices actually do overcommit by default?
Re: Static Allocation with Zig
#78Earlier quoted context omitted.
See https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TI... for motivation. - Operational predictability --- latencies stay put, the risk of threshing is reduced (_other_ applications on the box can still misbehave, but you are probably using a dedicated box for a key database) - Forcing function to avoid use-after-free. Zig doesn't have a borrow checker, so you need something else in its place. Static alloca…
> Forcing function to avoid use-after-free Doesn't reusing memory effectively allow for use-after-free, only at the progam level (even with a borrow checker)?
Notice that this kind of use-after-free is a ton more benign though. This milder version upholds type-safety and what happens can be reasoned about in terms of the semantics of the source language. Classic use-after-free is simply UB in the source language and leaves you with machine semantics, usually allowing attackers to reach arbitrary code execution in one way or another.
Re: Static Allocation with Zig
#79Earlier quoted context omitted.
> Forcing function to avoid use-after-free Doesn't reusing memory effectively allow for use-after-free, only at the progam level (even with a borrow checker)?
Yes, kind of. In the same sense that Vec in Rust with reused indexes allows it. Notice that this kind of use-after-free is a ton more benign though. This milder version upholds type-safety and what happens can be reasoned about in terms of the semantics of the source language. Classic use-after-free is simply UB in the source language and leaves you with machine semantics, usually allowing attackers to reach arbitrar…
On the other hand, the more empirical, though qualitative, claim made by by matklad in the sibling comment may have something to it.
[1]: In fact, take any C program with UB, compile it, and get a dangerous executable. Now disassemble the executable, and you get an equally dangerous program, yet it doesn't have any UB. UB is problematic, of course, partly because at least in C and C++ it can be hard to spot, but it doesn't, in itself, necessarily make a bug more dangerous. If you look at MITRE's top 25 most dangerous software weaknesses, the top four (in the 2025 list) aren't related to UB in any language (by the way, UAF is #7).
Re: Static Allocation with Zig
#80Earlier quoted context omitted.
> Forcing function to avoid use-after-free Doesn't reusing memory effectively allow for use-after-free, only at the progam level (even with a borrow checker)?
There's some reshuffling of bugs for sure, but, from my experience, there's also a very noticeable reduction! It seems there's no law of conservation of bugs. I would say the main effect here is that global allocator often leads to ad-hoc, "shotgun" resource management all other the place, and that's hard to get right in a manually memory managed language. Most Zig code that deals with allocators has resource managem…