> It's like coding to the Linux syscall interface instead of libc.
The right thing to do? I don't see why I would want to use libc.
On Windows, the stability guarantees are opposite to that of Linux. The kernel ABI is not guaranteed to be stable, whereas the Win32 ABI is.
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.
> I don't see why I would want to use libc
To make your code portable? Linux-only software is even worse than Windows-only
Nope, in UNIX proper syscalls and libc overlap, that is how C and UNIX eventually evolved side by side, in a way one could argue UNIX is C's runtime, and hence why most C deployments also expect some level of compatibility with UNIX/POSIX.
Linux is the exception offering its guts to userspace with guarantees of stability.