Live data from Hacker News

How safe is Zig?

scattered-thoughts.net

11–20 of 259 posts

Re: How safe is Zig?

#11

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

One interesting distinction is that it sounds as if - for Zig, this is a language feature and not a toolchain feature. Although if there's only one toolchain for zig maybe that's a distinction-without-a-difference. At least it's not opt-in, that's really nice. Believe it or not, there are lots of people who write and debug C/C++ code who don't know about sanitizers or they know about it and never decide to use them.

Re: How safe is Zig?

#12
I would like Zig to do more to protect users from dangling stack pointers somehow. I am almost entirely done writing such bugs, but I catch them in code review frequently, and I recently moved these lines out of main() into some subroutine:

  var fba = std.heap.FixedBufferAllocator.init(slice_for_fba);
  gpa = fba.allocator();
slice_for_fba is a heap-allocated byte slice. gpa is a global. fba was local to main(), which coincidentally made it live as long as gpa, but then it was local to some setup subroutine called by main(). gpa contains an internal pointer to fba, so you run into trouble pretty quickly when you try allocating memory using a pointer to whatever is on that part of the stack later, instead of your FixedBufferAllocator.

Many of the dangling stack pointers I've caught in code review don't really look like the above. Instead, they're dangling pointers that are intended to be internal pointers, so they would be avoided if we had non-movable/non-copyable types. I'm not sure such types are worth the trouble otherwise though. Personally, I've just stopped making structs that use internal pointers. In a typical case, instead of having an internal array and a slice into the array, a struct can have an internal heap-allocated slice and another slice into that slice. like I said, I'd like these thorns to be less thorny somehow.

Re: How safe is Zig?

#13

This was a great read, with an important point: there's always a tradeoff to be made, and we can make it (e.g. never freeing memory to obtain temporal memory safety without static lifetime checking). One thought: > Never calling free (practical for many embedded programs, some command-line utilities, compilers etc) This works well for compilers and embedded systems, but please don't do it command-line tools that are…

I've been writing a toy `wordcount` recently, and it seems like if I wanted to support inputs much larger than the ~5GB file I'm testing against, or inputs that contain a lot more unique strings per input file size, I would need to realloc, but I would not need to free.

Is that `wordcount` in Zig? My understanding (which could be wrong) is that reallocation in Zig would leave the old buffer "alive" (from the allocator's perspective) if it couldn't be expanded, meaning that you'd eventually OOM if a large enough contiguous region couldn't be found.

Re: How safe is Zig?

#14

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

Whoa the username checks out perfectly.

Re: How safe is Zig?

#15

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

> clang and gcc will both tell you at runtime if you go out of bounds [...] You can't have them all on at the same time because code will be unnecessarily slow

Yeah, so clang and gcc don't actually tell you at runtime if you go out of bounds. How many program ship production binaries with asan or ubsan enabled, to say nothing of msan or tsan?

Also you can't have them all on at the same time because they're not necessarily compatible with one another[0], you literally can't run with both asan and msan, or asan and tsan.

[0] https://github.com/google/sanitizers/issues/1039

Re: How safe is Zig?

#16

Earlier quoted context omitted.

I've been writing a toy `wordcount` recently, and it seems like if I wanted to support inputs much larger than the ~5GB file I'm testing against, or inputs that contain a lot more unique strings per input file size, I would need to realloc, but I would not need to free.

Is that `wordcount` in Zig? My understanding (which could be wrong) is that reallocation in Zig would leave the old buffer "alive" (from the allocator's perspective) if it couldn't be expanded, meaning that you'd eventually OOM if a large enough contiguous region couldn't be found.

It's in zig but I just call mmap twice at startup to get one slab of memory for the whole file plus all the space I'll need. I am not sure whether Zig's GeneralPurposeAllocator or PageAllocator currently use mremap or not, but I do know that when realloc is not implemented by a particular allocator, the Allocator interface provides it as alloc + memcpy + free. So I think I would not OOM. In safe builds when using GeneralPurposeAllocator, it might be possible to exhaust the address space by repeatedly allocating and freeing memory, but I wouldn't expect to run into this on accident.

Re: How safe is Zig?

#17
A lot of embedded devices and safety critical software sometimes don't even use a heap, and instead use pre-allocated chunks of memory whose size is calculated beforehand. It's memory safe, and has much more deterministic execution time.

This is also a popular approach in games, especially ones with entity-component-system architectures.

I'm excited about Zig for these use cases especially, it can be a much easier approach with much less complexity than using a borrow checker.

Re: How safe is Zig?

#18
post #2

And here is the table with Nim added; though potentially many GC'd languages would be similar to Nim: https://uploads.peterme.net/nimsafe.html Edit: noteworthy addendum: the ARC/ORC features have been released, so the footnote is now moot.

Thanks! I'd love to see a Dlang BetterC column too

Re: How safe is Zig?

#19

I would like Zig to do more to protect users from dangling stack pointers somehow. I am almost entirely done writing such bugs, but I catch them in code review frequently, and I recently moved these lines out of main() into some subroutine: var fba = std.heap.FixedBufferAllocator.init(slice_for_fba); gpa = fba.allocator(); slice_for_fba is a heap-allocated byte slice. gpa is a global. fba was local to main(), which c…

This. I believe it is in the works, but postponed to finish up self-hosted.

https://github.com/ziglang/zig/issues/2301

Re: How safe is Zig?

#20

I like zig but this is taking a page out of rust book and exaggerating C and C++ clang and gcc will both tell you at runtime if you go out of bounds, have an integer overflow, use after free etc. You need to turn on the sanitizer. You can't have them all on at the same time because code will be unnecessarily slow (ex: having thread sanitizer on in a single threaded app is pointless)

Neither Clang nor GCC has perfect bounds or lifetime analysis, since the language semantics forbid it: it's perfectly legal at compile time to address at some offset into a supplied pointer, because the compiler has no way of knowing that the memory there isn't owned and initialized. Sanitizers are great; I love sanitizers. But you can't run them in production without a significant performance hit, and that's where t…

State of the art sanitizing is pretty consistently in the Yes, the "just-enable-the-compiler-flags" approach can be expensive, but the tools exist to allow most people to be sanitizing most of the time. Devs simply don't know what's available to them.
Post reply on HN