Conversation

Jarkko Sakkinen

Edited 3 months ago
A typical #TUI #Rust application has usually about ~600 dependencies or similar figure.

A typical C applications has less than ten. C application might possibly be less "memory safe" language but you can statically analyze every bit and piece of the code base, including dependencies.

And by doing hat, you end up getting more verified, and *objectively* more memory safe build artifact ;-) 🤷

What many people especially in the Rust community completely have ignored, one side-effect of this new language popping, was igniting the heyday of the development of static analysis of the C language, which has *vastly* improved both in LLVM and GCC toolchains.

Just look at how amazing e.g. GCC 14 is when analyzing C code, and given the low amount of dependencies you can get pretty solid guarantees on safety of your code base.

Static analysis of C can *only* get better because the base language is compact and does not really grow anymore. One thing where C is factors more immutable is the language spec itself ;-) Rust language spec on the other hand is the most mutable spec ever invented, and run by a Github pull request process...

#rustlang #gcc #llvm #toolchain
4
3
6

@jarkko On the other hand: Dependencies in C/C++ tend to be much bigger than those in Rust. Qt/boost/gnome/... all would be several times more dependencies in Rust. In fact every C lib is at least two dependencies in Rust: foo-sys and foo.

I find it hard to compare numbers here, the eco-systems are so very different.

1
0
0

@hunger

I find it somewhat easy because the application category is well defined in my post:

  1. I based amount of C dependencies based on what I’m typically seeing in the project file. GNOME is a project umbrella, not a dependency.
  2. Dependencies might be larger but there are much less forks, larger user bases, which adds up to the QA and generally well-defined processes.
  3. For many Rust libraries I find sometimes hard to trust, given that they have not been exposed that much in the “warzone”. And this is sort of feature of the ecosystem too because you pile up your app stack from these nuts and bolts (also known as “crates”). You end up constructing yourself the “big dep”.
2
0
0

@jarkko Fewer deps does not help with memory safety mid-term either: You simply can not code without fail. There is no way to be memory safe -- and to *stay* memory safe -- without good tooling.

And static analysis is more limited in C than it is in rust: Aliasing is the bane of analysis and rust just has much less of that going on.

1
0
0
@hunger it is well anchored comparison also given the build artifact: ELF binary (or COFF/PE).
Also in binary analysis C wind by a large margin given its trivial binary structure, which is result of compact language spec with only constructs that are great fits for any possible microarchitecture ABI.
1
0
0
@hunger would take me ages to open code that argument so i just say that I can agree on disagreeing with your argument 😉
1
0
0
@hunger Except the one that I already mentioned:

1. Rust static analysis can get only worse over time, given the steady complexity growth in the spec.
2. C static analysis can get only better over time, given a stable and compact spec. And it does. Tooling for analyzing C is a whole multi-million industry of its own.
1
0
0

@jarkko Yeap, gnome is a umbrella project. So is Qt and boost :-) Any library in there would be several crates. It's easy to create and use crates, so you get lots of them :-)

But yes, I do not trust random crates either:-) It is random code on the internet, conveniently packaged for reuse.

But then I do not trust random C libs I find on github either. Much less so random C apps: Code reuse happens by copy/paste and inlining code to avoid having a dependency -- which is hard!

1
0
1
@hunger yup, I can more or less align with this!
0
0
0

@jarkko Both ELF and COFF are written to accommodate C... Rust has to jump through hoops to squeeze all the stuff it needs in (as does C++ and other languages).

That's where at least a part of the extra code comes from.

1
0
0
@hunger I do like Rust, I'm using it too, and have contributed to some upstream projects features and also have some things of my own going on too (still unreleased ASN.1 to bytecode compiler, and alternative super light-weight TPM2 stack).

I just generally learn best by applying "learn by hate"-methodology ;-)

Like when doing kernel dev, I look Linux more like how bad it is, and from that angle I find ways to improve it. And even look into how great NT kernel or Darwin are doing some things, whereas Linux is under-performing.
1
0
0

@jarkko Rust is build around local reasoning... I doubt that will be sacrificed for *any* feature. C has that too a much lesser degree (aliasing is part of that problem). At least academic papers about analysis (static and dynamic) I have seen recently seem to agree that analyzing rust is much easier due to its language design.

Most of the new rust stuff gets de-sugared down to existing HIR/MIR functionality, so complexity explosions is overrated I think ;-)

We will see what the future brings.

1
0
0

@jarkko You make a solid argument either way;-). I see the problem too, I just do not think C is that much better when you pull back the curtains. I found way too many copies of gzip in code bases for my liking 😉

"Sure, this code has no dependency -- just some random version of something with some patches on top copied straight into a folder a decade ago and not updated once since then."

Proper dependencies are way better than that IMHO. At least you can see the entire picture that way.

0
0
0
@hunger local reasoning is not something that i can measure, so pure ignore the whole concept ;-)
0
0
0

@jarkko I greatly dislike useless dependency explosion in the ecosystem.
e.g. Why does my project have to compile 10 different ways to print errors? Why do I need four different pretty-printing crates?

1
0
1
@codrusofathens yeah, it is f*****g horror story how this plays :-) absolutely hate rusty forking culture.
1
0
0
@codrusofathens and the whole narrative that Rust almost invented memory safety is like totally untrue.

E.g. in the backend Java has delivered the whole gist of memory safety literally decades and JVM's JIT is a monster dealing with server payloads... It is optimized by the best breed of Intel, ARM etc. companies for each micro-architecture.

When looking at beyond the hype I feel that there's exactly one area where I find Rust best tool so far: cli-interfaces. For tpm2-cli I chose Rust because input validation was easier with it than in my previous python experiments (I've done a small Python based stack for kselftest previously).

Not a revolution really ;-)
2
0
1

Jarkko Sakkinen

Edited 3 months ago
@codrusofathens ... and counter arguments are 90% of time qualitative arguments, e.g. "we have this contract/abstraction/invariant so you're wrong".

I only believe in quantitative arguments for the most part. E.g. spec growth is one of such, e.g. you can compare that to a spec that does not grow. Would be foolish to think that spec growth does not have a negative impact to static analysis.

But for any quantitative arguments it is hard to say anything conclusive. Can't beat Gödel's theory of incompleteness, right? ;-)
0
0
1

@jarkko Yeah, I'd rather do Java than C, but only barely. Java's big mistake was inheritance. I don't want to waste time clicking though ten levels and thirty pages of Oracle docs.

It's also quite competitive with lower-level languages—for example, an optimized program on GraalJVM (or whatever it's called) can often beat a naïve Rust program.

Rust's backend parallelism is superior to almost anyone else's, though. That's a huge win for the ecosystem. Plus, we have good SIMD wrappers.

1
0
1
@codrusofathens
Rust is pretty much owning WebAssembly at least. For wasm it is almost like what C is for bare metal.

So one probably quite widely used web stack in future has along the lines these layers:

1. JavaScript/TypeScript as orchestrator
3. Rust compiled into wasm as "client-side" latency backend.
3. Java in the "server-side" backend.

Makes sense because more stuff can offloaded to the client. For large batch computations Java is pretty solid, but for more latency sensitive stuff you'd want to use Rust.

And obviously it makes sense in any possible business to scale down the amount of investment to the "new", or like find a sweet spot for that investment...
1
1
0
@codrusofathens wasm had no previous "dominator", Rust came out with right timing and as a language it fits quite well to the wasm architecture. In all other domains there's something already existing, which people find useful and productive.
0
0
0

@jarkko I think it's remarkable (in a good way) that we're in a place where languages like Rust *and* radical improvements to time-tested C toolchains BOTH happen.

1
0
1
@valthonis Yep, that's what competition tends to do...
0
0
0