> A general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
Zig clearly doesn't actually care that much about building robust and reusable software if they're going to forgo Microsoft's decades-long backwards compatibility functionality for the dubious gains of using bare-metal APIs.
I think the only place where avoiding win32 is desirable is to write drivers, but zig already has support for some level of bare-metal development and I'm sure a package can provide shims to all ntdll utilities for that use-case.
I think it's pretty clear that they're doing it because it's a more fun challenge. As a low-level developer myself, I agree that using the lowest-level API possible is fun, especially if it's poorly documented and you have to try to try to preemptively mitigate breakage! But this is no mentality to have when you're writing a language ecosystem...
This might very well be a good idea. Microsoft is not going to change a vital piece of their OS just on a whim. I would wager that even if they wanted to, they would not be able to do so that easily. A large organization maintaining a large software with a billion users just does not move that fast.
> Unfortunately, yes. We consider this a problem for the anti-virus scanners to solve.
I don't think the anti-virus scanners consider Zig important enough, or even know about. They will not be the ones experiencing problems. Having executables quarantined and similar problems will fall on Zig developers and users of their software. That seems like a major drawback for using Zig.
There's no way I can ship a binary that flags the scanners. This wouldn't be the first language I've avoided because it has this unfortunate behaviour.
And expecting virus scanner developers to relax their rules for Zig is a bit arrogant. Some virus scanners started flagging software built with Nim simply because Nim became popular with virus authors as a means to thwart scanners!
In reality it will be a problem for the developers to solve, and the solution will be to use a different language lol
> [...] the worst case scenario is really mild: A new version of windows comes out, breaking ntdll compatibility. Zig project adds a fix to the std lib. Application developer recompiles their zig project from source, and ships an update to their users.
That assumes the application developer will continue to maintain it until the end of time.
Also "the fix" would mean developers wanting to support earlier Windows versions would need to use an older std library? Or is the library going to have runtime checks to see what Windows build its running on?
But they won't, because if there is one thing that Microsoft has always been extremely good at and cared for is backward compatibility. And changing Native API will break a ton of existing software, because even though undocumented it is very widely used.
they tell you not to use ntdll, and say they will change it whenever they want
and they have in the past
(they have had to moderate this policy with "containers", but it's still what they say)
If it's still relevant after the developer abandons it, someone else will probably fork it.
The ~only good thing that programmers have achieved in the past ~60 years has been Windows stability.
Create a popular programming language, and then make programs written in it not run on newer Windowses is just something else. I so hate this.
Was "robust, optimal and reusable" always "run an older Windows on your newer Windows to run Zig software"?
> Performance - using the native API bypasses the standard Windows API, thus removing a software layer, speeding things up.
But the article cites no bemchmarks
> Power - some capabilities are not provided by the standard Windows API, but are available with the native API.
Makes sense when you are doing something that needs that power, but that makes more sense as an exception to prefering win32 than a general reason to prefer native.
> Dependencies - using the native API removes dependencies on subsystem DLLs, creating potentially smaller, leaner executables.
Linking win32 is a miniscule cost. (unless you have a benchmark to show me...)
> Flexibility - in the early stages of Windows boot, native applications (those dependent on NtDll.dll only) can execute, while others cannot.
Is Zig being used for such applications? If so, why are the calls that the document says will be kept on win32 not an issue?
https://news.ycombinator.com/item?id=25997506 https://github.com/golang/go/issues/68678
Putting it on app developers to account for infinite forward compatibility is not at all reasonable.
The best outcome would be if many Zig apps become popular enough that Windows is forced to maintain backward compatibility for ntdll. The API is clearly superior to win32 as many other developers have discovered and discussed before. It’d be nice to force MS to take low lever programming seriously instead of chasing AI slop.
No, that's one of the reasons. The other one is that public kernel32 -> private ntdll design works.
Basically any thing documented on msdn in the API docs is considered stable.
Such as: https://learn.microsoft.com/en-us/windows/win32/api/winternl...
One could probably produce some sort of function pointer loader library with these tables, but at that point... Why not just use the documented APIs?
[1]: https://github.com/j00ru/windows-syscalls/blob/8a6806ac91486...
> [NtQuerySystemTime may be altered or unavailable in future versions of Windows. Applications should use the GetSystemTimeAsFileTime function.] [0]
So it does seem like a bad idea for a standard library.
[0]: https://learn.microsoft.com/en-us/windows/win32/api/winternl...
Then there's "Win32u.dll". These correspond to API calls from User32.dll, Gdi32.dll, etc. This DLL didn't even exist during the Windows 2000-XP era. This stuff is not well documented, and I don't know if this is stable.
Considering the level of the API. But it is total opposite comparing a bit deeper. Linux has a famous rule "WE DO NOT BREAK USERSPACE!" e.g. [1].
^1 https://docs.kernel.org/admin-guide/syscall-user-dispatch.ht...
A bit more comparable is OpenBSD where applications are very much expected to only use libc wrappers, which threw a wrench into the works for the Go runtime.
Which is perfectly fine to do and guaranteed to work forever because of Linus's policy that kernel updates aren't allowed to break userspace programs.
If in doubt, try and find examples of its breakage, semantic changes, etc.
It's the opposite of that. The Linux syscall is more stable than the (gnu)libc.
The right thing to do? I don't see why I would want to use libc.
Linux is the exception offering its guts to userspace with guarantees of stability.
And frankly, the Windows way is better. On Linux, the 'ABI' for nearly all user-mode programs is not the kernel's ABI but rather glibc's (plus the variety of third-party libraries, because Win32 has a massive surface area and is an all-in-one API). Now, glibc's ABI constantly changes, so linking against a newer glibc (almost certainly the 'host' glibc, because it is almost impossible to supply a different 'target' glibc without Docker) will result in a program that doesn't run on older glibc. So much for Torvalds' 'don't break userspace'.
Not so for a program compiled for 'newer' Win32; all that matters are API compatibilities. If one only uses old-hat interfaces that are documented to be present on Windows 2000, one can write and compile one's code on Windows 11, and the executable will run on the former with no issues. And vice versa, actually.
To make your code portable? Linux-only software is even worse than Windows-only
See for example this PR comment: https://github.com/rust-lang/miri/pull/4840#discussion_r2836...
This is already a problem with Linux binaries for systems that don't have a recent enough Glibc (unless the binaries themselves don't link to it and do syscalls directly).
(Reading the MFT is still faster. Yes, you need admin for that)
https://github.com/xfeeefeee/node-windows-readdir-fast https://www.npmjs.com/package/node-windows-readdir-fast
Windows only of course, but the concept is sound. Was also fun benchmarking to find out that parsing a binary stream was faster than creating a ton of objects through the node api (or json deserialization)
Here's one fun example from following development on Zulip: advapi.dll loads bcrypt.dll, which loads bcryptprimitives.dll. bcryptprimitives.dll runs an internal test suite every time it's loaded into any process. So if you can avoid loading advapi.dll, your process will start faster.
There's a reason they do that and it's not for shits and giggles. You could find yourself with broken ciphers and not know it.
Skipping the cipher (or hash - not sure now) tests seem like a good way to get exploited.
Unfortunately it makes too many false assumptions about interoperability between Win32 and the underlying native API that aren't true.
For example (and the Go runtime does this, much to my chagrin), querying the OS version via the native API always gives you "accurate" version information without needing to link a manifest into your application. Unfortunately that lack of manifest will still cause many Win32 APIs above the native layer to drop into a compatibility mode, creating a fundamental inconsistency between what the application thinks the OS capabilities are versus which Win32 subsystem behaviours the OS thinks it should be offering.
Frankly this is dumb. Zig hasn't been around long enough to have even seen any changes, so using this as a reason is just plain dumb.
The view that, if windows ever changes, the code must be recompiled is a naive view one would expect from a child, not from a group of experienced devs.