3 ms·
Ordinarily you're at the whim of the optimizer whether calls in tail position are made in a way that grows the stack or keeps it constant. musttail guarantees
by mtklein 3y ago
Ordinarily you're at the whim of the optimizer whether calls in tail position are made in a way that grows the stack or keeps it constant. musttail guarantees that those calls can and are made in a way that does not let the stack grow unbounded, even without other conventional -On optimization. This makes the threaded interpreter design pattern safe from stack overflow, where it used to be you'd have to make sure you were optimizing and looking carefully at the output assembly.
If nothing else musttail aids testing and debugging. Unoptimized code uses a lot more stack, both because it hasn't spent the time to assign values to registers, but people often debug unoptimized code because having values live on the stack makes debugging easier. The combination of unoptimized code and calls in tail position not made in a way that keeps stack size constant means you hit stack overflow super easily. musttail means that problem is at least localized to the maximum stack use of each function, which is typically not a problem for small-step interpreters. Alternatives to musttail generally involve detecting somehow whether or not enough optimization was enabled and switching to a safer, slower interpreter if not positive... but that just means you're debug and optimized builds work totally differently, not at all ideal!