* "First viable replacement for C" - C++ was invented decades before Rust.
* "Well-written C programs translate almost 1:1 to Rust" - C programs can be compiled with minimal changes as C++.
* "or didn't offer meaningful improvement in safety/concurrency/expressiveness." - C++ offers major improvements in all of those areas.
A lot of C programmers don't want to switch to C++ and they won't want to switch to Rust either, because they favor simplicity and neither Rust nor C++ are simple. They'll probably switch to golang for some stuff if anything and just stick to C for the rest.
Rust is complex because it's powerful.
C++ is complex because it's a mashup of overlapping features from different eras.
I don't write C++, because whatever I write will crash for subtle reasons and I'll be told it's my fault, because of course you don't do this when you use that feature.
I can write Rust with all its complexity, and as long as I get it to compile, I'm confident it works more reliably than any C++ that I could have written.
Note: Rust executables can be trimmed down by stripping them (not done by default, even for release builds) and using libc malloc instead of jemalloc. But even then, C wins by a lot.
Relevant blog post: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executab...
C links dynamically to its libraries. Rust does not (by default).
This overhead is a constant overhead so it rarely matters. When it does, you can strip it down further and get it to the same level as C.
This is not evidence of a fat runtime, just a different default compilation strategy that prodces larger binary executables. jemalloc is (an optional) part of the runtime, but the rest isn't.
I suspect rust hello world using those libraries is due to a lack of LTO? Hello world doesn't need any of those.
You'll get different results if you compile them with musl for truly static and fair binary size comparisons.
if I remember correctly you should compile with --nostd flag and provide _start function for loader to load your executable!
you can do same with rust too (But I think you should provide a special flag for compiler). You can find all of it on documentation.
It can do (roughly) everything C can, i.e. it's natively compiled, gives control of memory layout, and doesn't depend on a GC runtime.
Previous C killers were either dependent on a fat runtime (which isn't a big problem in general, but is a problem for some of niches dominated by C), or didn't offer meaningful improvement in safety/concurrency/expressiveness.