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.
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?
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.
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 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?
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.
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.)
> 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.
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.
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.
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.
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.
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.
reply