loading...

Can Rust replace C/C++ as a systems language?

kendru profile image Andrew Meredith ・1 min read

I have been watching the CMU Advanced Database Systems course lectures on YouTube and have been trying to implement some pieces of a database in Rust as I watch. I have been impressed with how easy Rust makes some of the high-level code (thank you, pattern matching, enums, Option type, et al.). The tooling is also incredible, thanks to Cargo, rustup, and Clippy. However, writing the kind of code that is necessary for databases, memory allocators, device drivers, and other classic "systems" software seems difficult at times.

Guaranteed memory safety may not be conducive to software that has a core need to manage memory. For example, a database needs to pack values together in contiguous memory and interpret the type of the data at runtime. This is not too difficult but requires the use of unsafe code - and losing the memory safety of the Rust compiler. Is Rust's memory safety desirable in a low-level programming language? At what point should the burden for preventing bugs be placed on the compiler, and at what point should it be on the developer and a good suite of unit tests?

I don't love C++, but I wonder if it could lead to simpler implementations of low-level software.

Posted on by:

kendru profile

Andrew Meredith

@kendru

I'm an application developer who is slowly evolving into a systems engineer. I <3 SQL databases and distributed systems.

Discussion

markdown guide
 

In C++, you write classes to abstract away memory access. When coding you lean on these classes instead of manually managing memory at each callsite. It's much the same with Rust - you'd wrap all the unsafe usage for your tool into a safe API, and still reap all the benefits of borrowck.

So, yes, I think Rust is a good fit for these domains. It's always difficult to write low level code, and Rust lets you offload more of that complexity to the compiler. All unsafe code will be localized, and you'd use tests and documentation to prove invariants.

 

Thanks! For my particular database project, the storage engine needs a lot of unsafe code because it is operating at the level of abstraction of memory management, but all of the code around it is still beautifully safe Rust. My gut feeling is that there are probably some domains where it makes more sense to write the core in unsafe Rust and some that would be better served by writing the same intrinsically-unsafe code in C and calling via FFI. Of course, the surface area of the unsafe code should be minimized in either case.

By the way, I have really enjoyed reading your posts!

 

I guess I'm not convinced that unsafe rust is worse than C-via-FFI. You still get to do all the same things, and don't have to futz with an interface layer. Even if a large amount of your code needs unsafe, you can still wrap it up neatly with safe abstractions, which you'd also be doing with a C library.

I don't personally perceive writing unsafe Rust to be much different than writing in C, is that not your experience? If it is significantly easier to implement in C, then it's probably worth it, but that's not been the case for me.

Likewise - your CLJS series is making me want to revist that stack, it's been a while.

 

I'm not an experienced Rust dev but many times what at first looked like a Rust limitation, after some thought, happen to be that I was trying to put a screw with a hammer and complaining for the messy result. I'm not saying thats the case but it might. In any case, to me even if you have no choice but use unsafe on as much as 10% of your code, which to me seems a lot, at least you can narrow your bug hunting to that 10%, which to me is much better than doubt of your entire codebase. And maybe in time you figure out how to reduce those 10% unsafe.

 

You can read this one to get the opposite view on the problem

drewdevault.com/2019/03/25/Rust-is...

 

Ooh - nice article. Not that I am an expert on systems languages, but some of the points really resonated with me.