I made a comment about this yesterday[0], but there's been a massive increase in people migrating from C to Rust due to LLMs.
In contrast to what the C to Rust migration book is recommending (using FFI to integrate Rust with C), I've found it much easier to start from scratch. I recently finished a project where I rewrote Postgres in Rust[1]. For context, Postgres is about one million lines of C code.
On one attempt, I tried using c2rust to convert Postgres into unsafe Rust code. That attempt succeeded in terms of getting working "Rust" code, but any attempt to change any piece to safe rust, would require thousands of changes across codebase. Even though I had working Rust code, I found it infeasible to get to working idiomatic Rust code.
Instead what I found to be more effective was starting a new codebase and rewrite each file from the Postgres codebase into Rust one at a time. This allowed me to guarantee that at all times the new codebase was idiomatic and simultaneously I could make one pass over the Postgres codebase to get working idiomatic Rust.
YMMV, but I found it way easier to generate a whole new codebase from scratch rather than incrementally rewrite an existing codebase.
Mainmatter head of engineering here. From what we've seen on real projects, I can confirm that asking an AI to migrate the code results at best in somewhat functional but unmaintainable code, and starting from scratch is a better approach… However, starting from scratch doesn't work if the legacy codebase is actively being worked on (eg bux fixes and new features and refactorings) or lacks test coverage and documentation.
Starting from scratch also implies one major release where suddenly it's all Rust (so very risky). In contrast, we found that it's a much smoother transition for end-users and maintainers when we approach large codebases progressively, module by module, while the C engineers continue working on the C code and learn Rust in parallel.
Of course, each migration is different but I wanted to clarify with our field experience.
The “Table of Contents” in the article (https://mainmatter.com/c-to-rust-migration-book/) looks like the very basic stuff and not especially interesting, but then the headings in the book itself (https://mainmatter.com/c-to-rust-migration-book/course/) look much more in-depth and don't seem to map onto the supposed ToC. I think they're misusing that term? I guess it's aspirational too as the book isn't finished yet.
I've spent a good amount of time with C, nowhere near mastery though. Is it worth still writing C, or better off just learning Rust if my goal is to write embedded/systems code?
Rust is worth learning, but your C skills will continue to be useful for embedded for a long time. Rust support in the embedded world is still growing and you will find yourself going between Rust and C on most projects unless you can carefully pick your platform for Rust support up front.
Coming from C I don’t think you’ll find Rust too foreign, once you internalize how the ownership rules work. In my experience the formal rules of Rust overlap a lot with behaviors that are good practice in C/C++ anyway, but there are some complicated concepts that you need to wrap your head around before expressing them in Rust becomes second nature.
Whether it would suit you, depends if you can learn to like Rust's approach of moving more work to the type system. In Rust you do certain things the Rust's way, period. Programmers used to C being unopinionated about everything find that objectionable.
C is a tool which requires expertise but then goes out of your way and let's you do things, and do things rather efficiently, with no overhead, and exactly how you want. If you want it to cut off your arm it will do this too. But if you want to abstract things away behind types, this can also be done too (and arguable should be done more often in C). Somebody should write a C to more modern and safe C migration book.
Depends how you define "can", because you can invent your own conventions not checked by the compiler, or even make a compile-to-C language.
But more directly, C barely lets you define non-NULL pointers. It doesn't have pointers that guarantee the data behind them is initialized, it doesn't have never-leaves-this-thread data types. Const merely guarantees that you can't (strongly shouldn't) mutate data, not that it definitely won't be mutated by any thread.
Depends exactly what you mean by embedded but Rust isn’t as common as people make it out to be there. In some aread it’s almost entirely unheard of. C will be king for a while yet. There’s a lot of Ada floating around too.
Depends on if your embedded system has a nice toolchain for it and/or how much suffering you are willing to endure. Another consideration is if you have to collaborate with others. Most programmers don't know Rust.
I made a comment about this yesterday[0], but there's been a massive increase in people migrating from C to Rust due to LLMs.
In contrast to what the C to Rust migration book is recommending (using FFI to integrate Rust with C), I've found it much easier to start from scratch. I recently finished a project where I rewrote Postgres in Rust[1]. For context, Postgres is about one million lines of C code.
On one attempt, I tried using c2rust to convert Postgres into unsafe Rust code. That attempt succeeded in terms of getting working "Rust" code, but any attempt to change any piece to safe rust, would require thousands of changes across codebase. Even though I had working Rust code, I found it infeasible to get to working idiomatic Rust code.
Instead what I found to be more effective was starting a new codebase and rewrite each file from the Postgres codebase into Rust one at a time. This allowed me to guarantee that at all times the new codebase was idiomatic and simultaneously I could make one pass over the Postgres codebase to get working idiomatic Rust.
YMMV, but I found it way easier to generate a whole new codebase from scratch rather than incrementally rewrite an existing codebase.
[0] https://news.ycombinator.com/item?id=48738985#48739882
[1] https://github.com/malisper/pgrust
Mainmatter head of engineering here. From what we've seen on real projects, I can confirm that asking an AI to migrate the code results at best in somewhat functional but unmaintainable code, and starting from scratch is a better approach… However, starting from scratch doesn't work if the legacy codebase is actively being worked on (eg bux fixes and new features and refactorings) or lacks test coverage and documentation.
Starting from scratch also implies one major release where suddenly it's all Rust (so very risky). In contrast, we found that it's a much smoother transition for end-users and maintainers when we approach large codebases progressively, module by module, while the C engineers continue working on the C code and learn Rust in parallel.
Of course, each migration is different but I wanted to clarify with our field experience.
> would require thousands of changes
But LLMs are great at this, provided you have a test suite to keep the process on the rails.
One link deeper is the actual content; can we link there instead?
https://mainmatter.com/c-to-rust-migration-book/course/
[flagged]
The “Table of Contents” in the article (https://mainmatter.com/c-to-rust-migration-book/) looks like the very basic stuff and not especially interesting, but then the headings in the book itself (https://mainmatter.com/c-to-rust-migration-book/course/) look much more in-depth and don't seem to map onto the supposed ToC. I think they're misusing that term? I guess it's aspirational too as the book isn't finished yet.
I've spent a good amount of time with C, nowhere near mastery though. Is it worth still writing C, or better off just learning Rust if my goal is to write embedded/systems code?
Rust is worth learning, but your C skills will continue to be useful for embedded for a long time. Rust support in the embedded world is still growing and you will find yourself going between Rust and C on most projects unless you can carefully pick your platform for Rust support up front.
Coming from C I don’t think you’ll find Rust too foreign, once you internalize how the ownership rules work. In my experience the formal rules of Rust overlap a lot with behaviors that are good practice in C/C++ anyway, but there are some complicated concepts that you need to wrap your head around before expressing them in Rust becomes second nature.
Technically, absolutely.
Whether it would suit you, depends if you can learn to like Rust's approach of moving more work to the type system. In Rust you do certain things the Rust's way, period. Programmers used to C being unopinionated about everything find that objectionable.
C is a tool which requires expertise but then goes out of your way and let's you do things, and do things rather efficiently, with no overhead, and exactly how you want. If you want it to cut off your arm it will do this too. But if you want to abstract things away behind types, this can also be done too (and arguable should be done more often in C). Somebody should write a C to more modern and safe C migration book.
Depends how you define "can", because you can invent your own conventions not checked by the compiler, or even make a compile-to-C language.
But more directly, C barely lets you define non-NULL pointers. It doesn't have pointers that guarantee the data behind them is initialized, it doesn't have never-leaves-this-thread data types. Const merely guarantees that you can't (strongly shouldn't) mutate data, not that it definitely won't be mutated by any thread.
> moving more work to the type system
Sounds right up my alley. Thanks to you (and other siblings) for the thoughtful replies.
Depends exactly what you mean by embedded but Rust isn’t as common as people make it out to be there. In some aread it’s almost entirely unheard of. C will be king for a while yet. There’s a lot of Ada floating around too.
Depends on if your embedded system has a nice toolchain for it and/or how much suffering you are willing to endure. Another consideration is if you have to collaborate with others. Most programmers don't know Rust.
> embedded/systems code?
Depends on platform for embedded. It not very pleasant to write rust if you have to think about binary size. For systems code - sure, use rust.
Please do a skill
"Use Claude"
[the end]
cheadergen is an open source tool that our Rust lead wrote – not sth. we sell or anything