Unsafe Rust is harder than C
Claims that “unsafe Rust is harder than C” ignite broader debate over how best to achieve memory safety and correctness in systems programming. Commenters contrast Rust’s strict aliasing and ownership rules—especially in unsafe and low-level data structures—with C’s looser but more error‑prone model, and some argue that model checking tools can make C code comparably safe in practice. Others highlight trade‑offs in ergonomics, tooling, syntax complexity, and performance, splitting over whether Rust’s steep learning curve and verbosity are justified by its safety guarantees and concurrency benefits.
Relative Difficulty: Rust vs C and Other Languages
- Several argue “unsafe Rust is harder than C,” because it must still uphold Rust’s invariants without compiler help.
- Many find safe Rust easier than writing correct C, especially for concurrency; others say C is simpler and faster to write, even if correctness is harder to prove.
- Some claim “correct C is not actually hard”; others strongly dispute this, citing frequent bugs even among experts and real-world CVE rates.
- Comparisons extend to Zig, C++, C#, Go, and GC languages; tradeoffs cited around safety, ergonomics, and runtime costs.
Memory Safety, Model Checking, and Tools
- GCC flags, sanitizers, and fuzzers are seen as catching only “low-hanging fruit.” Full memory safety is tied to undecidable problems.
- One line of discussion promotes C model checking tools (e.g., CBMC) as a practical way to approach Rust-like safety in C, via contracts, abstraction, and SMT solving.
- Skeptics question practicality at large scale and note low adoption and lack of widespread praise.
- Rust-side model checking (e.g., Kani) is mentioned as analogous for proving properties beyond what the compiler enforces.
Unsafe Rust Semantics and Aliasing
- A central point: Rust and C have different aliasing rules; unsafe Rust must still respect Rust’s stricter rules, unlike C.
- This makes certain low-level patterns (intrusive lists, pinned data) more complex in Rust.
- Clarification that “unsafe” means “unchecked by the compiler,” not “anything goes.” Rust’s rules still apply.
Data Structures and Allocation (Vec, Wakers)
- Debate over whether
Vecnecessarily reallocates on each push; multiple comments emphasize amortized allocation and explicit capacity control. - Some see using
Vecas sufficient for “no allocations in steady-state”; others focus on cases where you must move data out of a mutex or avoid reallocations entirely, prompting intrusive structures.
Concurrency and Type-System Guarantees
- Rust’s type system is praised for encoding thread safety (no data races in safe code) across crates and libraries.
- In C, unchecked shared mutability, weak aliasing guarantees, and undefined behavior around atomics make correct multithreading significantly harder.
Ecosystem, Ergonomics, and Learning Curve
- Rust tooling (cargo, docs, tests) and language features (sum types, pattern matching) are widely praised.
- Complaints: heavy syntax, mental overhead, long compile times, dependency chains, and complexity of
Pin. - Some see Rust’s design as beautiful and “mind-expanding”; others consider the syntax ugly and cognitively taxing.
Philosophy of Safety and Correctness
- Disagreement over how much early correctness matters: some emphasize prototypes and “good enough” C; others stress that most bugs are subtle and long-lived.
- Debate over whether type/memory safety advocacy is evidence-based or “religious”; responses highlight that safety doesn’t solve all bugs but removes a large, well-documented class of them.