Hacker News new | past | comments | ask | show | jobs | submit login

I don't want to come off dogmatically defending Rust, I code little Rust in comparison to JS, and I've done C and C++ for some embedded systems. C is a very different monster to most other languages, I find people defending C to be just as proud and defensive as Rust programmers.

To address some of your complaints: yes, there are a lot of concepts to understand. I like wrappers, I found it crazy that in C, you first declare a mutex_t variable, and then you specifically have to call chMtxObjectInit(*mutex_t mutex) to initialise it [1]. If you forget? UB, kernel panic sometime in the future. I think Mutex::new() is far cleaner, and it's namespaced without arbitrary function prefixes. Binaries are tiny in comparison to JS/Python with deps, they will be larger than C. Compile times aren't that slow and you can't make extra language features happen out of thin air.

In C, I've found that it's commonplace to do a lot of clever and mysterious pointer and memory tricks to squeeze out performance and low resource utilisation. In embedded, there's usually a strong inclination to using "global" static variables, even declaring them inside function bodies because it "limits the visibility/scope of the variable". Not declaring a static variable inside a function is what knocked a few points off my Bachelor's robotics project.

I personally don't like this. It puts a lot of pressure on the programmer to understand the order of execution, and keep a complex mental model of how the program works. Large memory allocation, such as a cache, can be hidden in just about any function, not just at the top of a file where global variables are usually defined.

It sounds like what you're trying to accomplish is inherently unsafe, hence the "preaching", as in it requires the programmer's guarantee that 1) the data is fully initialised before it's accessed and 2) once the data is initialised, it's read-only and can therefore safely be accessed from other threads. C doesn't care, it will let you do a direct pointer access to a static variable with no overhead. Where's the cost? The programmer's mental model. I haven't tried, but I imagine that Rust's unsafe block will allow you to access static variables, just like in C with no overhead, effectively giving your OK to the compiler that you can vouch for the memory safety.

Rust solutions: lazy_static crate (safe, runtime cost in checking if initialised on every access), RwLock<Option<T>> (safe, runtime cost to lock and unwrap the option), unsafe (no overhead, memory model cost and potentially harder debugging), extra &T function parameter (code complexity cost, "prop-drilling", cleaner imo). On modern hardware, the runtime cost is absolutely negligeable.

Why would you not want to use Rust for a large project? This seems a bit contradictory to me. The safety guarantees in my opinion really pay off when the codebase is large, and it's difficult to construct that memory model, especially with a team working on different parts. Instead, you overload that work to the compiler to check the soundness of your memory access in the entire codebase.

If you like C, by all means keep on using it, I enjoyed my forray into C, it's simple and satisfying, but would much prefer Rust, after spending a lot of time tracking down memory corruption. Rust's original design purpose was to reduce memory bugs in large-scale projects, not to replace C/C++ for the fun of it. We usually have a natural inclination to what we know well and have used for a long time. Feel free to correct me if something is wrong.

1: http://www.chibios.org/dokuwiki/doku.php?id=chibios:document...




The point was none of those rust crates worked, or required you to use mutex in the end which the solution would not actually need (not zero-cost abstraction). I would've fine using unsafe, but even with unsafe it felt like I was fighting the compiler. I would just write this particular function with C, or use the lower level C FFI functions instead.

I stand that rust is more fun to write when you work higher level, treat it higher level language, where you'll have less control over the memory model of program. It all starts breaking down and you need to become a "rust low-level expert" when you want to work closer to the memory model (copy-free, shared memory, perhaps even custom synchronization / locking models ...). It does make sense, but in my opinion figuring out how to map your own model into rust concepts is not trivial, it requires lots of rust specific knowledge, which will take a long time to learn IMO.

When unsafe was marketed to me, I thought it was a tool I could use to escape the clutches when I'm sure what I'm doing and don't want rust to fight me, but sadly it doesn't work that way in practice, but the real way is to actually write C and call it from rust.


Just for fun, I tried the static variable approach for myself. I have to agree with you, it's really hard. I gave up after half an hour. Rust doesn't seem to like casting references to pointers, which I understand, as I don't think there's a guarantee that they are just pointers. A &T[], for example, is a fat pointer (two words, also encodes the count). I think the correct approach here is either accept runtime overhead, or pass a context to each function as a parameter.

I also agree with your other statement. I think Rust tries to abstract a lot of behind into its own type system, such as Box<T> for pointers, whilst keeping it relatively fast. C is definitely the right tool for the job if you want direct memory access, I also think this is a relatively small proportion of people, working on OS, embedded systems or mission critical systems such as flight control/medical equipment.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: