Live data from Hacker News

When Zig Is Safer and Faster Than Rust

zackoverflow.dev

31–40 of 58 posts

Re: When Zig Is Safer and Faster Than Rust

#31
The premise of the Rust half of the article makes no sense. 'Rust has more rules' is not true, references have more rules, and in unsafe code, you aren't using them very much. Comparing the rules that apply to references in Rust to the rules that apply to raw pointers in C and Zig is nonsensical: if you transliterate the Zig code to Rust, no new problems appear! 'What if I create a reference' is easily solved by not creating a reference, just as you are not creating a reference in the Zig code (because Zig doesn't have them). Every problem on Rust's end was just trying to use references instead of pointers. The article then trumpets Zig's tracing allocator as a unique benefit, even though you can do the exact same thing in Rust.

Re: When Zig Is Safer and Faster Than Rust

#32
post #28
post #7

Apart from syntax sugar over which I agree should be improved, the argument sells to boil down to: my language doesn't enforce a borrow checker so it is UB safe. Which in my book is just not true. The allocator example the user gives is not really good since if he had another try in between the alloc/free I assume the memory would not be freed, Drop semantic is better in that regard. You can also set a global alloc t…

> try between the alloc/free The idiomatic way to handle that is with some combination of `defer` and `errdefer`. Then, in code, there are no lines between alloc/free, and if a try would exit before the free then you would instead first free anyway. > drop semantic is better in that regard The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power o…

You literally don't leak memory in safe rust, that is kinda of the whole point. If you use smart pointers sure you can leak but that is not only rust, any ref counted abstraction has that.

Drop IMO is preferred over defer because you can't forget to call a free. If you encapsulate your unsafe (which you should), you can guarantee it will be freed. I much prefer that. If you want to free early just call drop manually, after that if the memory is not freed then that on you to set an allocator basedon your needs.

Re: When Zig Is Safer and Faster Than Rust

#33
post #17
post #13

> Writing a substantial amount of unsafe Rust really sucks the beauty out of the language. I really disagree with this take, given the examples of unsafe code the article chose to exhibit. Trying to write C in Rust totally goes against the grain of Rust's ergonomics, which are oriented towards discouraging unsafe code patterns. It should be a pain to attempt something dangerous, and it should feel really easy to writ…

This sounds like just prescriptive orthodoxy. In fact lots of applications, including big chunks of Rust's own standard library, need unsafe to correctly express their algorithms (doubly linked lists and balanced trees are famous examples of things that can't be borrow checked, the use case in question appears to be a collected heap which would likewise need to live in the same space). Deciding that these areas "shou…

In Burroughs, still sold as ClearPath MCP, to use applications compiled with unsafe code blocks (NEWP is one of the first systems languages with unsafe concept), the admin has to enable their execution in first place.

Until then the executables are tainted and will trigger an error instead of being executed.

Only the standard library, and OS system tools, as Trusted Computing Base, are excepted from this.

This is the whole point of systems security, everything is unsafe down to silicone, the whole point is reducing the amount of Trusted Computing Base that has to be manually validated and certified.

Re: When Zig Is Safer and Faster Than Rust

#34
post #32
post #28

Earlier quoted context omitted.

> try between the alloc/free The idiomatic way to handle that is with some combination of `defer` and `errdefer`. Then, in code, there are no lines between alloc/free, and if a try would exit before the free then you would instead first free anyway. > drop semantic is better in that regard The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power o…

You literally don't leak memory in safe rust, that is kinda of the whole point. If you use smart pointers sure you can leak but that is not only rust, any ref counted abstraction has that. Drop IMO is preferred over defer because you can't forget to call a free. If you encapsulate your unsafe (which you should), you can guarantee it will be freed. I much prefer that. If you want to free early just call drop manually,…

I like Drop. Memory leaks in Rust are incredibly uncommon. But they are considered memory safe. Box::leak is declared safe, as per the leakpocalipse right before 1.0.

A memory leak that is still pointed at by a dangling pointer is not going to cause UB, even though it is still a bug.

Re: When Zig Is Safer and Faster Than Rust

#35
post #32
post #28

Earlier quoted context omitted.

> try between the alloc/free The idiomatic way to handle that is with some combination of `defer` and `errdefer`. Then, in code, there are no lines between alloc/free, and if a try would exit before the free then you would instead first free anyway. > drop semantic is better in that regard The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power o…

You literally don't leak memory in safe rust, that is kinda of the whole point. If you use smart pointers sure you can leak but that is not only rust, any ref counted abstraction has that. Drop IMO is preferred over defer because you can't forget to call a free. If you encapsulate your unsafe (which you should), you can guarantee it will be freed. I much prefer that. If you want to free early just call drop manually,…

> You literally don't leak memory in safe rust, that is kinda of the whole point.

That's a common misconception. Safe Rust prevents use-after-free, double-free, accessing uninitialized memory, (an extremely constrained form of) data races, and a number of other things. It doesn't give a rip about leaks beyond a best effort. Leaks do not violate memory safety.

Part of the reason it doesn't care is because it's hard to infer your intent. A common class of bug is accidentally boxing a reference to something you'd like to drop (this and similar flaws afflicted Actix till at least the 3.0 release). Rust confirms you don't have UAF and that you don't drop the data before you're done with it, but by accidentally writing it so that it lives nearly forever that drop is never executed.

Rust, similarly, makes no guarantees about drop's behavior at any point in time (other than that it won't be executed to soon and should usually attempt to be executed eventually), but definitely not near program shutdown or similar. It's especially dangerous because a huge fraction of programs run correctly regardless most of the time.

Re: When Zig Is Safer and Faster Than Rust

#36
post #28
post #7

Apart from syntax sugar over which I agree should be improved, the argument sells to boil down to: my language doesn't enforce a borrow checker so it is UB safe. Which in my book is just not true. The allocator example the user gives is not really good since if he had another try in between the alloc/free I assume the memory would not be freed, Drop semantic is better in that regard. You can also set a global alloc t…

> try between the alloc/free The idiomatic way to handle that is with some combination of `defer` and `errdefer`. Then, in code, there are no lines between alloc/free, and if a try would exit before the free then you would instead first free anyway. > drop semantic is better in that regard The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power o…

> The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power outages and the like), and Rust's sets up a point in time where the given cleanup code is _allowed_ to run.

You're making it sound like Drop is regularly not called, which could lead someone to think that you're talking about them not running on panics, which they do: https://play.rust-lang.org/?version=stable&mode=debug&editio...

The reason they are allowed to run is because panics can be configured to be abort, so people are discouraged from using Drop to maintain safety constraints. But any language will have issue executing code before exiting if you go out of your way to set things up so normal unwinding doesn't occur.

> It solves UAF, but it makes performance harder to reason about and makes leaks easier to write (a common theme in my complaints about Rust -- it's mostly a nice language, but many of the design choices slightly encourage leaky code, so most projects of any size and complexity have leaks).

I don't see how Drop causes leaks.

> Having drops be that easy to write also encourages programmers to think in terms of small units of data rather than collections and common lifetimes, typically resulting in increased execution times.

Beyond my skepticism about the mechanism being a significant source of performance degradation, writing collections that take responsibility over dropping their contents in one go isn't particularly difficult or restricted by the language.

Re: When Zig Is Safer and Faster Than Rust

#37
post #27
post #4

Zig has a singular focus on doing low level systems programming and it shows. Rust is very nice for systems programming, but it's not as ergonomic as Zig at all. Of course, it's a much nicer and more comfortable general purpose language. I think both languages are great and hope to see them used more and more in the future. It's much better to debate when to use Zig and when to use Rust then go back to the dark days…

Then there's Nim which is great as a general purpose language and has great ergonomics too.

But, ran by a BDFL that doesn't ever want to become a foundation and share power, is known to throw tempter tantrums, and freaks about LGBTQ people and creators.

Re: When Zig Is Safer and Faster Than Rust

#38
post #32
post #28

Earlier quoted context omitted.

> try between the alloc/free The idiomatic way to handle that is with some combination of `defer` and `errdefer`. Then, in code, there are no lines between alloc/free, and if a try would exit before the free then you would instead first free anyway. > drop semantic is better in that regard The drop trait has its warts too. Zig's version sets up a point in time where the given cleanup code _will_ run (ignoring power o…

You literally don't leak memory in safe rust, that is kinda of the whole point. If you use smart pointers sure you can leak but that is not only rust, any ref counted abstraction has that. Drop IMO is preferred over defer because you can't forget to call a free. If you encapsulate your unsafe (which you should), you can guarantee it will be freed. I much prefer that. If you want to free early just call drop manually,…

> You literally don't leak memory in safe rust, that is kinda of the whole point.

Memory leak is not the same as dangling reference. A loop pushing too many values into a vector can be considered as a memory leak.

Re: When Zig Is Safer and Faster Than Rust

#40

The premise of the Rust half of the article makes no sense. 'Rust has more rules' is not true, references have more rules, and in unsafe code, you aren't using them very much. Comparing the rules that apply to references in Rust to the rules that apply to raw pointers in C and Zig is nonsensical: if you transliterate the Zig code to Rust, no new problems appear! 'What if I create a reference' is easily solved by not…

> What if I create a referecnce is easily solved by not creating a reference

Except it isn't easy. Rust implicitly creates references constantly and in unsafe code it may be UB for those to exist. It's why Rust has all the crazy offsetof macros and such because you can't reliably do the obvious &raw (*struct_pointer).field

Post reply on HN