8 ms·
Rust-style lifetimes. The work by deallocing when the lifetime goes out of scope. No more memory leaks from non-reference-counted stack pointers (heap allocs).
by himom 8y ago
Rust-style lifetimes. The work by deallocing when the lifetime goes out of scope. No more memory leaks from non-reference-counted stack pointers (heap allocs).
Or: use Rust.
- charliesome 8y agoRust lifetimes prevent use-after-frees, but they're totally orthogonal to buffer overflows. Rust mitigates buffer overflows by automatically inserting bounds checks and panicking on out-of-bounds access. Your program still crashes, but you don't potentially open yourself to RCE. Ultimately Rust's automatic bounds checks rely on higher level facilities in the language for dealing with slices that C just doesn't have.
- TheDong 8y agoRust has more than just bounds-checks. Rust heavily encourages the use of iterators and functional-programming both of which prevent buffer overflows by making code that could overflow less idiomatic.
- stochastic_monk 8y agoThis can also be provided by C++ by .at() or iteration through containers.
- lewisinc 8y agoI'm not super familiar with C++, however Rust has an advantage over this example as it avoids iterator invalidation at compile time by assigning the iterator a lifetime.
- pjmlp 8y agoWhile not the same thing, some C++ compilers like Visual C++ do that at runtime in debug builds.
- bluejekyll 8y agoIf we’re talking about switching to a new language from C, why only go almost safe with “modern” C++ and not all the way to fully safe Rust? I’m not trying to be snarky, but the thread was about Rust as an improvement to C and you just threw C++ into the mix... which isn’t as safe.
- unsatchmo 8y agoI like Rust, but based on the difficulty I’ve had writing even the most basic of bare metal software in it, it will be like 10 or 15 years before the community and the tooling are ready to do kernel or device driver work in Rust. C may have a lot of foot guns but it’s really easy to learn and use.
- bluejekyll 8y agoRust took me longer to learn than most languages, I'll grant you, but I'd say after 3-4 weeks I was writing safer code than anything I ever wrote in C. Not claiming to be an expert in C, but I paid my share of blood and tears with it, and all I can say is that it's worth the effort to learn Rust for the huge guarantees the language gives you in the same contexts as C. If you're interested in baremetal, there are a number of tutorials out there, all focused on different things. I really love the TockOS tutorials, they are really awesome for getting across some of the different benefits at different levels: https://github.com/tock/tock/tree/master/doc/courses/rustconf https://github.com/tock/tock/tree/master/doc/courses/rustcon... And then more raw OS stuff: https://os.phil-opp.com/ https://os.phil-opp.com/
- pjmlp 8y agoRust is already at a good level when you are writing low level OS infrastructure code and CLI utilities. For GUI software or GPGPU development, it still needs to mature a bit more.
- bluejekyll 8y agoYes, though I think patterns are starting to emerge that will start taking hold. For example: https://raphlinus.github.io/personal/2018/05/08/ecs-ui.html https://raphlinus.github.io/personal/2018/05/08/ecs-ui.html I mostly think this is a gap in common libraries at the moment and decent coding practices. We’ll see what happens with all of that. Personally I’m more focused on web-backends, micro-services, and DNS, so GUIs don’t generally present problems for me.
- pjmlp 8y agoAnd if using Visual C++, operator[] and iterators are bounds checked in debug builds.
- pjmlp 8y agoJust like systems languages about the same age as C already had proper arrays and foreach loops, while not foolproof they were much safer than what C has left us.
- cesarb 8y agoThe most important of these language facilities, IMO, is Rust's "fat pointers". In Rust, a "&[T]" is not a single word but two: the first word is a pointer to the first element like in C, but the second word is the number of elements. This keeps both together all the time; you don't normally have the pointer separated from the number of elements (although you can separate them if you really want to), which is what allows the compiler to insert the bounds checks. (Another interesting use of fat pointers is in Rust's "trait objects", where the first word of a "&Trait" is a pointer to the object, and the second word is a pointer to the vtable. In C++, the pointer to the vtable is part of the object; in Rust, it's part of the reference.)
- greglindahl 8y agoDebugging C compilers have been using "fat pointer" implementations for decades, to do bounds checking, but of course it's dangerous to use that into C code that assumes things about the sizes of pointers. Fortran added array descriptors in 1990, when it made arrays first class objects. That was a quite visible language change. So this is a well-studied area with lots of implementations you can look at.
- dbaupp 8y agoThat's not how lifetimes work, and their strength is not in stopping memory leaks: both because they do not do that, and because memory leaks aren't the biggest problem. Rust's lifetimes record when values are valid and when they're not that exist in the code statically (essentially the same ones that exist in C++ code), in a way that allows the compiler to check that they're being used correctly, that a valid (i.e. "can be used") value never points to or uses an invalid one.