Using indices isn't bad for performance. At the very least, it can massively cut down on memory usage (which is in turn good for performance) if you can use 16-bit or 32-bit indices instead of full 64-bit pointers.
> "unsafe" (which is strictly more dangerous than even C, never mind Zig)
Unsafe Rust is much safer than C.
The only way I can imagine unsafe Rust being more dangerous than C is that you need to keep exception safety in mind in Rust, but not in C.
In Rust, it's not just using an invalid reference that causes UB, but their very creation, even if temporary. For example, since references have to always be aligned, the compiler can assume the pointer they were created from was also aligned, and so suddenly some ending bits from the pointer are ignored (since they must've been zero).
And usually the point of unsafe is to make safe wrappers, so unafe Rust makes or interacts with safe shared/mutable references pretty often.
If you need to make everything in-house this is the experience. For the majority though, the moment you require those things you reach for a crate that solves those problems.
No it's not? The Rust burrow checker, the backbone of Rust's memory safety model, doesn't stop working when you drop into an unsafe block. From the Rust Book:
>To switch to unsafe Rust, use the unsafe keyword and then start a new block that holds the unsafe code. You can take five actions in unsafe Rust that you can’t in safe Rust, which we call unsafe superpowers. Those superpowers include the ability to:
Dereference a raw pointer
Call an unsafe function or method
Access or modify a mutable static variable
Implement an unsafe trait
Access fields of a union
It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any of Rust’s other safety checks: if you use a reference in unsafe code, it will still be checked. The unsafe keyword only gives you access to these five features that are then not checked by the compiler for memory safety. You’ll still get some degree of safety inside of an unsafe block.Obviously if you can keep using references then it's not less safe, but if what you're doing can be done with references, why would you even be using `unsafe`?
For those saying unsafe Rust is strictly safer than C, you're overlooking Rust's extremely strict invariants that users must uphold. These are much stricter than C, and they're extremely easy to accidentally break in unsafe Rust. Breaking them in unsafe Rust is instant UB, even before leaving the unsafe context.
This article has a decent summary in this particular section: https://zackoverflow.dev/writing/unsafe-rust-vs-zig/#unsafe-...
Imo, the more annoying part is dealing with exception safety. You need to ensure that your data structures are all in a valid state if any of your code (especially code in an unsafe block) panics, and it's easy to forget to ensure that.
Um, what? Unsafe Rust code still has a lot more safety checks applied than C.
>It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any of Rust’s other safety checks: if you use a reference in unsafe code, it will still be checked. The unsafe keyword only gives you access to these five features that are then not checked by the compiler for memory safety. You’ll still get some degree of safety inside of an unsafe block.
Laughs in graphics programmer. You end up using indices to track data in buffers all the time when working with graphics APIs.
At the same time, if using indices was universally better, then we'd just use indices everywhere, and low-level PLs like Rust would be designed around that from the get go. We don't do that for good reasons.
Unsafe rust still has a bunch of checks C doesn’t have, and using indices into vectors is common code in high performance code (including Zig!)