Hacker Newsnew | past | comments | ask | show | jobs | submit | AndyKelley's commentslogin

I propose let's break up a bunch of these monopolies to give you and your colleagues more options, more competition for your resume.

invitation tree. lobste.rs already has it, works great.

bitpacked structs, good enums, arbitrary sized integers, optionals + non-nullable pointers, fast compiler, zig fmt, unit testing, ability to use standard library and the rest of the third-party ecosystem on freestanding, std.ArrayList, std.AutoArrayHashMap, std.MultiArrayList, std.crypto, more productive type system, comptime, SIMD, slices, labeled switch continue, error handling, custom panic handler, stack traces on freestanding, error return traces, zero bit types, the build system, package management, aligned pointers, untagged union safety, multi-object for loops, inline switch cases, semantically guaranteed inline functions, inline loops

In Zig, error codes are fundamentally a control flow construct, not a reporting mechanism.

The pattern here is to return something like error.Diagnostics for all errors that have been reported via diagnostics.

The only reason you'd have a different error code would be if the control flow should be different. For example error.OutOfMemory makes sense to be separate because it's a retryable error, which means it should be handled by different control flow.


Thanks Andy.

Would you endorse the pattern I described in my article if the calling code could have other uses for the diagnostic info than just logging?

In my project I decided that the CLI main should be the place with a reporting mechanism. All the internal code is agnostic to how errors are handled. Many errors could be retried, even if they are currently not, and in some cases you also need extra diagnostic data in order to retry. For example if 1/4 plugins fails to load, I would need to know which one failed to ask the user interactively where to find it or whether to skip it before retrying. There's a few different errors like this, and layers between the handling code and the error source code, which is how I ended up with the union(enum) diagnostic keyed by error code pattern.

It seems that "error codes aren't a reporting mechanism", practically speaking, means that internal application code should just log its own error and return a generic error code that bubbles up unhandled out of main. You decided that this wasn't ok for allocation failures and encourage retrying those, which I find to be inspiring, but apparently most types of application errors are fine to essentially log and ignore. So that is confusing.

I love Zig, and look up to you a lot, so thanks for all your efforts over the years!


Do you think it would fundamentally be a mistake to thread data along with error type through the error return path, or is it just that it costs too much say from a calling convention perspective or some other technical reason? Is it related to ownership?


100% agreed.


flagged for being slop


Sorry to bother you, but I couldn't find any news on this, only a comment you made back in 2018 on GitHub; do you know if the HTTP APIs in Zig's standard library are here to stay, or if some of them might be removed? Another commenter wrote that the HTTP client is used for Zig's package management, but there is also the HTTP server.


HTTP client and server stay for sure.


No ads on Wikipedia tho, not even after 25 years.


The first fundraising banner on wikipedia was in 2003. That is unquestionably an advertisement, and not even an ethical one given the misleading nature of their campaigns these days.


I’m going to say this is a different ballpark. They are fundraising for themselves.. on their own website..

That’s quite different from shoving ads in your face where it doesn’t belong. Like an ad for Copilot on a YouTube video.

IMO it’s distinct.


never thought I’d see fundraising compared to ads but here we are… :)


Do you not think those intrusive banners and popups implying that Wikipedia is about to imminently go broke unless you give them money, are ads?


I think you're letting pedantry hinder you from seeing a useful pattern.


I shall take that as a no, then.

I don't think it takes pedantry to think advertising in order to solicit funds for a non-profit is still advertising.

If anything the criteria I would apply is does it diminish the user experience while attempting to motivate the viewer to act in a manner that benefits the advertiser.

May I ask why you do not consider it advertising? Is it because it is asking for donations? Because it is a non-profit? If so, why would those factors exempt them?

I am certainly not alone in thinking their fundraising campaigns are intrusive https://news.ycombinator.com/item?id=33175098


As an example, a line that they don't cross, but a for-profit company absolutely would, is compromising the integrity of the encyclopedia articles. For example, a marketing department would pay a lot of money for Wikipedia to delete or soften https://en.wikipedia.org/wiki/Controversies_of_Nestl%C3%A9 but they'll never do that, not for profit at least.


It's about who they're fundraising for. Wikipedia fundraising for Wikipedia is fundamentally different than selling out ad space to the highest bidder.


I've always admired your work, Walter. Keep it up!


Thank you for the kind words, Andy!


This affects static libc only. If you pass -dynamic -lc then the libc functions are provided by the target system. Some systems only support dynamic libc, such as macOS. I think OpenBSD actually does support static libc though.


> I think OpenBSD actually does support static libc though.

How does that work, with syscalls being unable to be called except from the system’s libc? I’d be a bit surprised if any binary’s embedded libc would support this model.


For static executables, “the system’s libc” is of course not a thing. To support those, OpenBSD requires them to include an exhaustive list of all addresses of syscall instructions in a predefined place[1].

(With that said, OpenBSD promises no stability if you choose to bypass libc. What it promises instead is that it will change things in incompatible ways that will hurt. It’s up to you whether the pain that thus results from supporting OpenBSD is worth it.)

[1] https://nullprogram.com/blog/2025/03/06/


> How does that work, with syscalls being unable to be called except from the system’s libc?

OpenBSD allows system calls being made from shared libraries whose names start with `libc.so.' and all static binaries, as long as they include an `openbsd.syscalls' section listing call sites.


Can't you just have one syscall(2) to rule them all? https://man7.org/linux/man-pages/man2/syscall.2.html


You can. There is a thread-unsafe implementation here <https://gist.github.com/oguz-ismail/72e34550af13e3841ed58e29...>. But the listing needs to be per system call number, so this one only supports system calls 1 (_exit) and 4 (write). It should be fairly easy to automatically generate the complete list but I didn't try it.


Sorry I got mixed up with FreeBSD: https://codeberg.org/ziglang/zig/issues/30981 (original github link has more information)


Not all of libc is syscalls. E.g. strlen() is zib libc but open() goes to system libc.


Good point. C's "freestanding" mode, analogous to Rust's nostd, does not provide any functions at all, just some type definitions and constants which obviously evaporate when compiled. Rust's nostd not only can compute how long a string is, it can unstably sort a slice, do atomic operations if they exist on your hardware, lots of fancy stuff but as a consequence even nostd has an actual library of code, a similar but maybe less organized situation occurs in C++. Most of the time this is simply better, why hand write your own crap sort when your compiler vendor can just provide an optimised sort for your platform? But on very, very tiny systems this might be unaffordable.

Anyway, C doesn't have Rust's core versus std distinction and so libc is a muddle of both the "Just useful library stuff" like strlen or qsort and features like open which are bound to the operating system specifics.


This use case is unchanged.

If you specify -target x86_64-windows-gnu -lc then some libc functions are provided by Zig, some are provided by vendored mingw-w64 C files, and you don't need mingw-w64 installed separately; Zig provides everything.

You can still pass --libc libc.txt to link against an externally provided libc, such as a separate mingw-w64 installation you have lying around, or even your own libc installation if you want to mess around with that.

Both situations unchanged.


That's cool. I imagine I could also maintain a MinGW package that can be downloaded through the Zig package manager and statically linked without involving the zig libc? (Such that the user doesn't need to install anything but zig)

That's a good way to sell moving over to the zig build system, and eventually zig the language itself in some real-world scenarios imo.


do you suspect it will be possible to implement printf??

while we're talking about printf, can i incept in you the idea of making an io.printf function that does print-then-flush?


It's completely possible to implement printf. here is my impl (not 100% correct yet) of snprintf for my custom libc implemented on top of a platform I'm working on <https://zigbin.io/ab1e79> The va_arg stuff are extern because zig's va arg stuff is pretty broken at the moment. Here's a C++ game ported to web using said libc running on top of the custom platform and web frontend that implements the platform ABI <https://cloudef.pw/sorvi/#supertux.sorvi> (you might need javascript.options.wasm_js_promise_integration enabled if using firefox based browser)


yeah I just thought there are "compiler shenanigans" involved with printf! zig's va arg being broken is sad, I am so zig-pilled, I wish we could just call extern "C" functions with a tuple in place of va arg =D


The only thing C compilers do for printf, is static analyze the format string for API usage errors. Afaik such isn't possible in zig currently. But idk why'd you downgrade yourself to using the printf interface, when std.Io.Writer has a `print` interface where fmt is comptime and args can be reflected so it catches errors without special compiler shenigans.


I'm thinking: do a translate-c and then statically catch errors using my zig-clr tool.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: