6 ms·
The key difference to me is where you use “probably”. Rust and even WASM reflect a lot of the system behavior that’s become the norm among modern hardware platf
by swatcoder 4y ago
The key difference to me is where you use “probably”. Rust and even WASM reflect a lot of the system behavior that’s become the norm among modern hardware platforms.
But those norms are still not universal and it’s useful to maintain an understanding of other viable architectures. C was born from a time of of extremely high innovation and experimentation in hardware architecture and it’s baked many of those possibilities into its language. Often, those are the very footguns that can make writing commercial software in C something to be considered carefully, especially because performant and safer alternatives like Rust exist.
Yet, using C is still sometimes the right choices for commercial software and remains a unique instrument for privately expanding one’s understanding of system and hardware architecture.
The quoted claim about C doesn’t have to be wrong just to argue that Rust might often be a better choice in practice for commercial bare metal programming on common systems. It’s making a subtly different claim, and the difference can matter.
- saagarjha 4y agoAmusingly Rust is needing to revisit some of the earlier choices it made that were “obvious” on modern hardware architectures, because we have even newer ones that don’t behave that way.
- int_19h 4y agoCan you give some examples?
- saagarjha 4y agoHere's a recent one: https://faultlore.com/blah/fix-rust-pointers/ https://faultlore.com/blah/fix-rust-pointers/. The problem there was essentially that Rust assumed sizeof(size_t) == sizeof(intptr_t). If bounds checking makes it into hardware then two's complement will also get thrown out the window.
- tialaramex 4y agoBecause C has both size_t and intptr_t and a billion other magic types which can be adjusted to suit more architectures it was able to successfully "adapt" to CHERI where Rust makes such an adaptation enormously expensive (now all your word size integers are 128-bit). On the other hand of course, first CHERI doesn't make much sense in Rust, you would not invent all this expensive stuff if your language was memory safe, CHERI exists because people just keep writing C and C++ software and there must be a hardware mitigation - CHERI is that mitigation. If you see a lot more practical CHERI hardware, evidently it was just too hard to give up on these terrible languages. Secondly though, the main thrust of Aria's article isn't CHERI. It's compelling to have physical hardware that shows off the problem by making usize and isize twice as big, but in practice Aria is talking about provenance which affects your machine and your C programs. In C provenance is just... not defined. WG14 did I believe actually write (or is in the process of writing) a Technical Report explaining some sort of PNVI-ae variant (Provenance Not Via Integers, Address Exposed) two decades after DR260 but that's not the C language standard it's just a TR, and it's not the final word on the matter. So Aria's Strict Provenance Experiment isn't Rust trying to catch up to where C was on this, it's Rust trying to do stuff C didn't get to yet in ~50 years of development. And in both languages this is about issues that are completely unrelated to your real hardware. The point here is that addresses which your memory hardware actually has, don't have provenance, but pointers which exist in your programming language do.
- saagarjha 4y ago> CHERI doesn't make much sense in Rust CHERI was obviously designed for C and C++, but that doesn't mean it doesn't make sense to use with Rust. Capabilities are generally useful primitives, and allow you to do things like eliminate bounds checks because they are not handled by the hardware. Provenance is kind of weird in that it is very underspecified and compilers have mostly been flying by "do whatever feels right" for many years, which has mostly worked until recently, when people decided to really sit down and hammer out proper rules for the things people expect to work. CHERI has accelerated those efforts because whatever gets picked for provenance is going to be implemented on that platform and they would like capabilities to line up with whatever they decide. In a sense, this is the opposite problem, where C decided to not really specify behavior at all and now needs to clean up its act, rather than overspecifying and being unable to adapt to new hardware. It's good that it's being cleaned up but mostly aligned with what people have already been doing.
- tialaramex 4y agoI think that I'd have said this claim about C (being closer to the metal) was wrong even 10-15 years ago when I was mostly writing C for a living. Ignore the Rust stuff entirely if you prefer. What you can learn about in C is the C abstract machine, but the abstract machine is not any modern computer. It starts as a greatly simplified model of the PDP-11, a computer which hasn't been commercially relevant in decades. So, on the one hand it's not much like the machines we own today, yet on the other hand it's also not like any real machine ever because all the complexities the C designers didn't express in their language are absent from the abstract machine. Sometimes this is an intentional deviation to make C simpler than a PDP-11, which is understandable but not so useful. Much worse though are places where they just didn't know. The actual PDP-11 has specific semantics because it was a real thing, you could try stuff and find out. You could experiment. However the abstract machine is imaginary, and so where its properties were under-specified you can't just experiment there actually is no answer. WG14 (the C language committee) has tried, since it came into existence, to straight out some of this and choose definite answers, but it's a long way from finished. So on the one hand, C is bad theoretically because it ignores much of what theoretical CS discovered in subsequent decades, but then on the other hand C is bad practically because its abstract machine models how somebody in the 1970s thought a 1970s computer worked, so it's wrong and it's 50 years old. And again, I write these things as, IMNSHO an expert C programmer. I'm somebody who has found bugs in GNU libc and who wrote their own debugging tools so they could live debug problems which only happened in a production service. I'm not speaking out of ignorance, but out of understanding.
- swatcoder 4y agoI respect what you're saying here about a "C abstract machine" that's disjoint from any particular real hardware, and that it introduces its own troubles through the abstraction, and I think with agree with all that. But I'm not sure how to draw that out of your original comment, or even how to interpret the original comment while "ignoring the Rust stuff entirely". That comment seems to be suggesting that Rust exposes its users to the bare metal just as much as C does, so if you take that comparison out, it doesn't seem like it's saying anything at all. C is flawed, and is not even ideal as a window into bare metal (because of its own abstract machine), but Beej noted that it's more connected than any "present-day" language, and that claim does seem to hold.