Live data from Hacker News

Unsafe Zig Is Safer Than Unsafe Rust

andrewkelley.me

91–100 of 105 posts

Re: Unsafe Zig Is Safer Than Unsafe Rust

#91
post #83

Had never heard of zig. Does it also provide memory safety without a GC like Rust?

No, not to the same extent.

It attempts to make C-style memory management as safe as possible, and also make it easy to use different memory allocators, but does not attempt advanced techniques like borrow checkers.

There's also a pretty good metaprogramming system, so it may be possible to implement some smart memory-management libraries.

Zig is about simplicity. It's a C (and partly C++) replacement, not a Rust replacement.

Think of it this way: I could easily imagine a TCC-like, dirt-simple, super-fast compiler for Zig. I'm not sure we'll ever see the same for Rust.

That's nothing against Rust, just saying they have very different goals.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#92
post #90

I find it so funny people are so fixed on bounds checking. A minimal run time environment is good. It's easier to port and runs faster. Further, there are more issues than bounds checking. Also a big part of it is companies don't really pay for quality software. They just care about software that works mostly made to cost. I don't see rust reducing this cost much except. First, one still has to interact with hardware…

> I find it so funny people are so fixed on bounds checking. A minimal run time environment is good. It's easier to port and runs faster. Further, there are more issues than bounds checking.

Bounds checking on arrays is a compile-time check in Zig. Other forms of bounds-checking can be disabled in release-mode.

I don't see a single compelling reason why you wouldn't at least want bounds checking in debug mode. If you're out of bounds, something is wrong, and it's always better to get an early and precise error about it.

In Zig you can take slices of arrays or pointers, which contain a pointer and a length. This is not just about safety, it's also a convenience. There's a lot of usecases where you want to pass around both a pointer and a length.

Considering how many extremely serious bugs have resulted from a lack of bounds-checking, and considering the relatively low run-time overhead of doing it (especially with some decent optimizations from the compiler), I don't find it funny at all.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#93
post #90

I find it so funny people are so fixed on bounds checking. A minimal run time environment is good. It's easier to port and runs faster. Further, there are more issues than bounds checking. Also a big part of it is companies don't really pay for quality software. They just care about software that works mostly made to cost. I don't see rust reducing this cost much except. First, one still has to interact with hardware…

> I don't see rust reducing this cost much except.

At scale, a language with a module system will reduce cost substantially.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#94
post #72

Earlier quoted context omitted.

> To summarise, I still don't see how these two sentences are different: ... To "observe unsafe behavior" means I can write a program that does something safe, e.g., a data race or invalid memory access. It's possible to write library X and Y in such a way that I can observe unsafe behavior using both X and Y in my program, without putting "unsafe" blocks in my program. This is possible even if I can't do the same th…

I'm still not understanding: other than the hardware/global state thing in another comment in this thread[1], what's a program that demonstrates this "composing safe interfaces is unsafe" property? The example in the paper is not one, it was a bug for crossbeam to mark its API safe. [1]: I'm ignoring this case, because it's somewhat completely impossible to solve: there's no way Rust (or any language) can control thi…

There is a way. You have to meticulously prove operations down to machine code to not have externally observable side effects.

You can weaken the condition by excluding, say, timing effects or cacheline effects. (Say hello to Spectre)

This means you get to prove bounded access and data race freedom on any piece of memory safe code touches. Likewise prove bounded access for all unsafe code and correct cpu flag and state handling.

It it's not as bad as it seems - you can use the machine code prover designed for seL4 as a good starting point.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#96
I’m finding Zig easier to learn and hold in my head so that also helps me right correct code and safe code. Zig is pretty much one man’s work and is very impressive. I’m still playing with Rust but I am using Zig as my C replacement right now.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#97
post #3

Rust is a language that offers you lots of compile time checks, and an escape hatch called unsafe that says “trust the programmer here.” Yes, it is possible—and easy—to make mistakes in the place where you have asked to be trusted, not checked. We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust. We should also think of if we can improve…

I would suspect that this particular issue is not necessarily a defensive coding problem.

https://gist.github.com/andrewrk/182ace5dee6c4025d8c4b0ca22c...

https://github.com/andrewrk/libsoundio/blob/fc96baf8130b52ba...

I've written that code before, and I know better (but then, all the world's an x86 box, right?) But first, I'm not sure how to make that code not broken (yes, that's an education issue), and second, the same arguments can be made about all the issues Rust is designed to prevent.

This really should be a compiler warning.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#98
post #62

Earlier quoted context omitted.

I'll be an anti-crustangelist and say that I've actually avoided moving a C++ project I've been working on over to Rust because (1) I'm finding that fixing some of the previous code's pre-C++xx practices is suitable enough and (2) I've only written a few small things in Rust up to this point and learning the 30% or so more that I'd need to in order to get things fixed would take more time and has more unknowns. Grant…

Well, if you want to write a tree using indices in a local array instead of pointers for better locality and memory footprint (which is ideal for many situations), you run into the difference between language pointers and computer science pointers. That's not even something that Rust will be smart enough to help you do properly.

In fact (unless something has changed dramatically without my getting the memo), that's how you would write many data structures in Rust---either for better memory behavior or you have cycles and Rc won't cut it. You have to use a vector of nodes and indices as pointers; if you try using references, the borrow checker comes and kicks sand in your face.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#99
post #4
post #3

Rust is a language that offers you lots of compile time checks, and an escape hatch called unsafe that says “trust the programmer here.” Yes, it is possible—and easy—to make mistakes in the place where you have asked to be trusted, not checked. We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust. We should also think of if we can improve…

It will be interesting to watch the proportion of safe/unsafe code in large Rust codebases over time.

At a guess, it will increase until the necessary-but-not-currently-handled constructs are dealt with (arena-based memory management, I'm looking at you) and then decrease asymptotically. Already in Rust, if you adopt C++ STL idioms (and don't want to squeeze more performance out) and don't need to visit currently-unwrapped interfaces, you won't need unsafe at all.

Rust is a very good C++ replacement.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#100
post #54

Earlier quoted context omitted.

Thanks! I'm not convinced that the statement in the paper translates into what you said: the key piece of that paragraph is "or seems to be". The Leakpocalypse problem was one piece of code (crossbeam's scoped threads API) was relying on an invariant that doesn't actually hold ("destructors will always run"). It was, fundamentally, a bug in the `unsafe` code in crossbeam, meaning it was incorrect for crossbeam to cal…

> To summarise, I still don't see how these two sentences are different: ... To "observe unsafe behavior" means I can write a program that does something safe, e.g., a data race or invalid memory access. It's possible to write library X and Y in such a way that I can observe unsafe behavior using both X and Y in my program, without putting "unsafe" blocks in my program. This is possible even if I can't do the same th…

The definition of what you're allowed to do with `unsafe`, however nebulous its specifics may be at the moment, is that such a situation is a bug in one or both of those libraries, not their composition.

To put it another way, if you can't observe unsafety with X or Y alone, but you can with both together, then at least one of them has given you a new capability that you did not have before. Either that new capability is not truly safe, and thus the bug is providing that capability, or it exposes the other library relying on something not truly safe, and thus the bug is relying on that property.

The important point here is that, by definition, at least one of X or Y will have to change when such a situation is discovered, in order to preserve the property that composing safe interfaces is safe.

Post reply on HN