5 ms·
None of Rust's language features allocate; not arrays, not closures, not iterators. Everything is stack-allocated by default. Rust code doesn't malloc unless yo
by kibwen 10mo ago
None of Rust's language features allocate; not arrays, not closures, not iterators. Everything is stack-allocated by default. Rust code doesn't malloc unless you use a library that calls malloc; in other words, exactly like C. Rust fully supports turning off the parts of the standard library that perform allocation, and this is precisely what embedded code and the Linux kernel does. So Rust already gives you full control.
- alexpadula 10mo agoGreat to know!
- jsheard 10mo agoYeah, it's not ideal that the standard library currently has blind spots around allocation and I hope those get resolved eventually, but if you're rolling everything from scratch in C anyway then it's not much of a stretch to likewise roll your own Rust primitives in places where the included batteries don't work for you.
- nialv7 10mo agowell, as an example, Vec::push doesn't have a way to report allocation failure. it will just panic, which is not acceptable in the kernel.
- imglorp 10mo agoThat seems like an enormous question. Is anyone working on it?
- pixelesque 10mo agoThere's experimental/nightly support for things like: `push_within_capacity()` which is a more manual way (user-space code would have to handle the return code and then increase the capacity manually if required) of trying to handle that situation.
- tialaramex 10mo agoAnd of course the kernel - which doesn't even use Rust's Vec but has its own entire allocator library because it is the kernel - likewise provides https://rust.docs.kernel.org/next/kernel/alloc/kvec/struct.Vec.html#method.push_within_capacity https://rust.docs.kernel.org/next/kernel/alloc/kvec/struct.V... Vec::push_within_capacity is a nice API to confront the reality of running out of memory. "Clever" ideas that don't actually work are obviously ineffective once we see this API. We need to do something with this T, we can't just say "Somebody else should ensure I have room to store it" because it's too late now. Here's your T back, there was no more space.
- kibwen 10mo agoSure, which is a perfectly acceptable default considering that most code is not in a position to observe allocation failures (because of OS-level overcommit, which is nearly always a good thing), and furthermore most code is not in a position to do anything other than crash in an OOM scenario. If you still want to have control over this without going full no_std, Rust has Vec::try_reserve to grow a Vec while checking for allocation errors, as well as several nightly functions coming down the pipe in the same vein (e.g. Vec::try_with_capacity, Vec::push_within_capacity).
- koakuma-chan 10mo agoI think this is bullshit. If you are running out of memory, you can, for example, choose to stop accepting more work ("backpressure"). I am always advocating for Rust, but this is one thing I really disagree on. I think Zig gets this right.
- ViewTrick1002 10mo agoNow you need to ensure that your entire error path does not allocate or you have to deal with allocation errors in the error path as well. Trying to apply backpressure from memory allocation failures which can appear anywhere completely disconnected from their source rather than capping the current in memory set seems like an incredibly hard path to make work reliably.
- smj-edison 10mo agoIn Zig's case, the entire stdlib never allocates on failure, and most libraries follow the same pattern. The philosophy of Zig is allocation/creation can fail, but freeing/destroying must never fail. It's caused me to be really thoughtful with how I design my data structures, and often made me use better ways of representing metadata.
- ViewTrick1002 10mo agoHow do you log or tell the world about the state of the program without allocating?
- ziml77 10mo agoThat's why you don't use std in this case. You limit yourself to things defined in core.
- Cyph0n 10mo agoYep, the “split” between core and std is brilliant. It enables so many usecases: one example I ran into recently is compiling Rust (core) to eBPF.
- dnautics 10mo agoyou understand that stack allocation can OOM too?
- craftkiller 10mo agoCan C gracefully recover from running out of stack space?
- fulafel 10mo agoDepends on your definition of graceful but the C standard doesn't preclude handling it and there's POSIX interfaces such as sigaltstack / sigsetjmp etc that fit and indeed some code like language runtimes use this to react to stack exhaustion (having first set up guard pages etc).
- kibwen 10mo agoOr in short: no, C is no better than Rust at gracefully recovering from stack overflow, either in theory or in practice.
- deleted 10mo ago[deleted]