3 ms·
How does Zig protect against stack overflow? To make a "100% panic-safe program" you must disallow recursion.
by pcwalton 4y ago
How does Zig protect against stack overflow? To make a "100% panic-safe program" you must disallow recursion.
- csande17 4y agoZig basically does plan to disallow recursion: https://github.com/ziglang/zig/issues/1006#issuecomment-534660820 https://github.com/ziglang/zig/issues/1006#issuecomment-5346... More specifically, it'll force you to allocate memory for your recursive functions on the heap (and thus handle the possible resulting OOM condition).
- pcwalton 4y agoDo you disallow function pointers/closures/virtual methods too, since these can be used to smuggle recursion into the semantics without the compiler being able to statically detect it? You'd have to heap allocate every call to a function pointer, which would be very slow (see how much benefit apps get from PGO which for a long time mostly amounted to optimizing virtual calls).
- csande17 4y ago> Do you disallow function pointers/closures/virtual methods too [...] Maybe? Of these features, AFAIK Zig only has function pointers, and they already don't seem to interact very well with other parts of the language. I wouldn't be surprised if they restricted them to comptime-only usage or made "how much stack space does the function need" part of the pointer type or something.
- Schroedingersat 4y agoDisallowing recursion is one possibility (IIRC misra guidelines forbid it). In some circumstances, static proofs are also possible. IIRC it's still an open problem in zig as to what the possible language features will be while keeping this guarantee, but the goal is to be able to have recursion in some circumstances and still provide the possibility of stack-overflow-safety with a performance tradeoff, and to know when you've stepped out of the bounds where that is possible. Here's a thread I'm at least a year out of date on https://github.com/ziglang/zig/issues/1006 https://github.com/ziglang/zig/issues/1006 The general philosophy is to give the programmer tools to know what the consequence of a choice will be as far as that doesn't hamstring them overly. Ie. the compiler can tell you when a stack overflow is possible, and it's up to you to decide what to do about it (or whether it is wrong because you know something it doesn't).
- pcwalton 4y agoThe trouble here is the same problem that affects tons of static analyses: what do you do about higher order functions. I'm pretty skeptical that heap allocating every call to a function pointer/closure/virtual method is going to be fast enough.
- fancl20 4y agoWhat do you mean by saying heap allocation? Do you mean syscall or libc? Zig has a extremely explicit requirement for any allocation. You can have a preallocated region of memory in the allocator for recursion and only move the needle for each “heap allocation”.
- pcwalton 4y agoAh, I see, it's a split stack. Well, we experimented with those in Rust for Rust->C calls and they were not fast enough (also, they cause problems with debuggers and tooling). Perhaps if virtual calls are uncommon, though. At that point I have to wonder what the advantage is over just using explicit checks for overflow on the machine stack though.
- deleted 4y ago[deleted]
- Schroedingersat 4y agoYou're still forcing a mindset onto the language that isn't present. It's not 'a split stack' or any other particular solution. You pass in an allocator and it does it whichever way your chose allocator picks. The goal is to explore sections of design space you're completely ruling out from before you even start.