Rust for C Engineers: Safe Systems Programming

Hello Everyone,

Rust for C Engineers: Safe Systems Programming is a book from FromC2Rust Publications is now live.

The book is designed on establishing Rust foundation and written for C engineers to help them migrate to Rust. It presents C and Rust examples sequentially, explaining Rust fundamentals through direct comparison.

FromC2Rust Publications

Honest feedback is appreciated.

I only have what’s available in the Amazon preview (first 20 pages of the book) but I’m noticing a problem in this section:

Using rustc manually like “rustc hello.rs” in a is in fact not quite sufficient, nor is there any actual practice of “small programs use rustc”. The case for very small programs is actually in the process of getting nicer support from cargo.

For users of manual rustc commands, you’ll at the very very least always want to provide an --edition=2024 argument, otherwise you’re setting yourself up for confusion if you run into any of the subtle details where editions can make a difference!

Perhaps it could be worded as "small projects can use rustc directly" implying larger ones will need something more

Thanks for pointing this out and for sharing the link.

Will revise this section. Will present rustc as a way to understand the compiler and for quick experiments. Will present Cargo as the standard workflow for both small and large programs.

Thanks for the nice point about specifying edition when using rustc. I will add a note recommending an explicit edition for consistency. The default edition depends on the installed compiler.

Thanks for the review comments. Sure, will frame it as " Perhaps it could be worded as "small projects can use rustc directly " implying larger ones will need something more"

It's rare to see a rust project that doesn't use cargo - the only one I can remember is Beazley's lifty - an interesting little program - and 1st one I have seen from him.

If you are new to rust, I think it is nice to see the compiler first without the builder/package manager.

Thanks Jesper for the comment! Agree with you on the point that for new people adopting Rust , it can add lot of cognitive overload to know/learn about builder/package manager on day1. For the book, as you rightly said, have introduced compiler first and also based on review comments above, have added small section on cargo build as well .

Sorry, but there is no "cognitive overload". All books I have read (and written :slight_smile: ) use Cargo from the beginning, and only shortly mention that for trivial programs rustc can be also used on its own. Cargo is a central component of Rust, and basic Cargo use is very easy (cargo new, cargo build, cargo run). Advanced cargo commands, and package management, is typically introduced later.

I had a short look at your text, I think your writing style is quite nice. Are you a native English speaker? But of course, the first twenty pages of a book are not enough to judge it -- and actually, I have some doubts that 300 pages can teach even the most basic fundamentals of Rust. So whoever would buy and read your book, still would have to study another, more complete introductorial text, and later read some advanced books. Have you read my book? It was also intended for people who have already some experience in systems programming, and regard the official tutorials as a bit verbose. But it took me 500 pages, and I really tried to present only the most basic fundamentals.

A final remark: You are discussing the term "variable binding", introduced by a nice description how variables are declared in C. Unfortunately I was not able to copy that text section here from Amazon, so I can refer only from my memory. I would suggest to emphasize a bit more, that Rust's term "binding" is only a formal description, and that internally variable declarations are in principle identical as in C, with the exception that Rust enforces that variables are always initialized before use. The term "binding" confuses actually some people, as it might indicate some form of indirection. So it might be a good idea to explicitly say that "binding" is more an abstract concept, and does not indicate that the generated machine code is different from C.

Sorry -- yesterday I tried hard to not reply at all, but with your last reply you somehow provoke my ramblings.

In fact "bindings" is a generic compiler internal term I've seen across several languages, useful to refer to any association between a symbol and a name.

I never used Cargo, it isn't in my tool chain. I'm an ordinary C programmer, I didn't read the book either, I use "vibe coding" and rustc. But I have right of keeping own opinion, Rust is for everyone, not only for few Rust experts. Am I right?

Did anyone suggest otherwise? It's true Cargo may be the overwhelming default, and a huge pain to avoid if you want to pull in public crates, but I don't think anyone's made value judgements on avoiding the use of it, at most just warning what you're getting yourself into?

When I started learning programming, I started from learning an assembler. Saying more, I even did my first programs in raw machine instructions, since an assembler even didn't exist for my processor. Later, I switched to C, and didn't touch an assembler anymore, just did some instructions occasionally. Rustc is a kind of an assembler for Rust programming, so it's obvious that the author of the book mention it first. Actually, rustc is a very powerful, simply people do not know all secrets of it. Regarding limitation yourself from crates.io? I do not think so. I also use lot of third party crates. What I do?

  • search crates.io for crates of my interest
  • inspect .toml of them for extra dependencies (actually crates.io makes it for you)
  • if the crate has 0 or just few dependencies, check its repository out and build the crate using my manifest and build tool (manifest is same level of simplicity as .toml)

Rebuild the crate .rlib, when update rustc or the crate itself. Everything is very simple.

The process you describe sounds an order of magnitude more complicated that just typing:

cagro run

Anyone using Make files to build their Rust?

Only in the happiest path is just running rustc on the crate source enough.

Let's say you want to use the very popular serde crate:

  • There's a bunch of fiddly disabling default features in a dependency crate then re-adding them in your own default features that you need to figure out
  • You need to replicate the build.rs file behavior which sets a bunch of rustc cfg flags and generates a private.rs file.
  • You need to add the serde-core crate as it's dependency and implement it's build.rs cfgs
  • You probably want the derive feature, so also import the serde-derive crate
  • EDIT: make sure, of course that you dont try to replicate that build.rs file, since that's excluded from the published crate and is just for development.
  • That of course, has three transitive dependencies common for most proc-macro crates: proc-macro2, quote, and syn, which transitively depend on unicode-ident
  • serde-derive is a proc-macro crate, so make sure you set the right make deps to rebuild it on rustc version change, and to always use the host triple if you're cross-compiling!
  • probably a bunch more details I've missed...

Compare this relatively easy case to the cargo experience:

cargo add serde -F derive

I don't think it's at all sensible to compare these two experiences and say the first is "very simple", before you even get to updating dependencies and resolving compatible versions.

To be clear, there are absolutely situations where you do want to go through the first route, I have myself (integration with an existing C++ build system), it's just not really a situation you should prefer. Even if you need hermetic builds, a simple cargo vendor locally then cargo build --offline for your automated builds is normally sufficient.

I agree. Thanks for this comment.

Even easier would be asking an LLM to do it for you. Simple and easy aren't the same thing, and IMO it's better to be biased towards the former than towards the latter, especially in educational materials. Cargo is easy to use, but it is not simple.

Nice to meet another author here. Thanks for taking the time to read and share detailed feedback.

I agree that Cargo is essential and the standard workflow in Rust. The book starts with rustc to keep the initial focus on the core language and then introduces Cargo shortly after as the primary way to build and run programs.

The intent is mainly to help C engineers build a simple mental model first, similar to using gcc directly before introducing a build system.

The point about “binding” is very helpful. I will refine that section to make it clear that the term is mostly conceptual and does not imply indirection, and that in practice it behaves similarly to variables in C, with Rust enforcing stricter compile-time guarantees.

Appreciate the thoughtful comments

Thanks for the detailed explanation, that’s a very helpful breakdown.

I completely agree that once dependencies, features, build scripts, and proc-macros come into the picture, using Cargo is the only practical approach.

The intent in the book is limited to the early learning phase, where users write several standalone programs to understand Rust design differences with C like ownership model.
Cargo is introduced shortly after and emphasized as the standard workflow.

The goal is not to replace Cargo, but to sequence the learning so that the core concepts are clear before adding ecosystem complexity.

Appreciate you calling this out, the distinction is important. Thanks for this clear and detail article.