Hacker News new | ask | show | jobs
by pcwalton 3811 days ago
Point by point:

> All you need to do is take the address of the GPIO register then toggle the bit.

Yes, and that is unsafe. Rust makes you put that in an unsafe block, to encourage you to build safe interfaces. This is a good thing.

> No name mangling.

The alternative to name mangling is not having a module system, with all the fun name conflict issues that come with it. Rust made the right decision here.

> No error handlers to override.

C has no concept of a panic handler because what would be panics in C are undefined behavior. Undefined behavior is bad for safety and understandability of the code. Having to declare an error handler is a small price to pay.

> It does seem odd to me that so many of what would be compiler options in C are hard coded.

Because Rust is safe by default. That's one of its most important features. Being more like C in the ways you mention would mean compromising that principle.

1 comments

After having played around with Rust a bit and seeing it used in some non-trivial applications I've grown to like it a lot, despite being an initial skeptic. However it's aggravating that in every post about Rust which raises valid criticisms about the language (in this case having to do with the ease with which C allows you to do low level programming), those associated with the Rust project leap to its defense and suggest that Rust's decisions are right for every situation.

Just because Rust can't easily do things that C can doesn't make it a bad language, but it does mean that, shockingly, there are somethings that Rust isn't as well positioned for as other languages are.

Similarly, there are things that C is bad at. Both at the high level and the low level. At the low level it hides too much of the CPU's features so for some very low level programming you need to drop to assembly. At the high level it has obvious deficiencies, many of which Rust addresses, but for interfacing with the actual hardware it is tough to beat C in terms of convenience.

Of those three issues, I see not sectioning off unsafe code as the only real defensible choice when comparing C to Rust. Whether you should have to type "unsafe" is a legitimate tradeoff; if all your code is unsafe, the unsafe keyword adds noise.

Undefined behavior and the lack of namespacing don't fall into this category, though. C would be a better language all around if it required that null pointer dereference trap to an error handler (at least on hardware with an MMU or MPU). It would also be a better language if it had a module system.

Not every engineering decision is a tradeoff. Sometimes certain decisions are just better all around. I think that modules and error handlers fall into this category.

> Not every engineering decision is a tradeoff.

Scratch the "not". For example, if I have a small-enough code-base, a module-system, is not worth it, unless it has zero cost. Or if the module system doesn't fit my needs, it will often be easier to create what I need if I don't have to work around what is there. Same with error handlers.

Every engineering decision is a tradeoff, though you may be in a space where the tradeoffs obviously point in one direction.

A module system is always worth it because every program needs to use library functions. Even if you think you don't, LLVM will generate calls to library functions for ordinary code; for example, if you move structures around on the stack, LLVM might just decide to call memcpy(), even if you didn't ever import string.h. (Checking your code after the fact to verify there are no library calls doesn't get around this because a new version of the compiler might add a library call where there wasn't one before.) Now you want some mechanism to isolate your code's names from the library's names. That's a module system.
Does bare metal Rust also use memcpy() or other library functions? If so, how are those linked into the final binary?
Yes, LLVM will assume three or four functions exist regardless. The rlibc crate provides a Rust implementation of them, so you just add it and you're done. https://github.com/alexcrichton/rlibc
They are usually provided by libc, but if you do low level stuff they are provided by other means.