See https://www.gnu.org/software/libc/manual/html_mono/libc.html...
See https://www.gnu.org/software/libc/manual/html_mono/libc.html...
I also know that #ifdefs are a bad practice with many pitfalls so their use should be kept to a minimum. There is a treatise on the subject written in the early ‘90’s that I now see is very much relevant, judging by your comment. I wish I could quote it but since I’m using a smartphone to type this it’s too much hassle to find it.
Regardless, from a software architecture’s point of view, introducing a GNUism or a Linuxism where it isn’t strictly necessary is an obviously bad idea.
How’d you fare with that GCC build on the mailing list from couple of years back, by the way?
As long as it has a default way to fall back to that works everywhere, there is no harm in platform specific code guarded by #ifdefs or other but similar mechanisms provided by the language you use (golang has platform and OS detection!)
Dump the built-in preprocessor macros between two different compilers on the same OS and diff the output, it should become immediately clear what I mean. Now go to a different OS and do the same thing and you’ll see that the number of possible combinations of defines to pick explodes, and depending on the situation, the common subset might not even be useful for portability, as in not enough overlap.
Libc doesn't even remotely offer what some libraries want and it leaves out everything that OS can offer on top of POSIX and libc.
And what if I want to support Windows, Linux and BSD? Windows doesn't really have a libc and is definitely not even remotely compatible with POSIX.
Windows does have a libc, but unlike UNIX where it comes with the OS, on Windows it comes with Visual Studio. That's what the "Visual Studio redistributables" are, since Windows has no linker maps and therefore no ABI versioning. Also, Windows has had a POSIX subsystem since the Windows NT days. That's what Windows Services for UNIX ("Interix") runs on.
I'm not saying don't use #ifdefs at all; what I am saying is don't use any OS-specific features if you want your program to be portable, or at least don't use those OS specific features which would immediately preclude usage of your software on other operating systems.
The only exception to this rule is if you are specifically writing software optimized for an operating system, like for example AmigaOS, or illumos/Solaris, or FreeBSD. However, unlike GNU/Linux based operating systems, it is a practical affair to find enough common functionality in illumos/Solaris and the BSD's to write software optimized for all of those operating systems and still be portable between all of them. The same does not hold true for software which has been written using GNU features because they are completely proprietary to GNU and require porting to BSD's and illumos. Sometimes, it's not even feasible to port those features because they are misfeatures or so badly designed that they are broken out of the box.
But this is exactly what #ifdefs solve.
You both have a portable program and can rely on OS-specific features. You can #ifdef GNU behaviour so that you can use the GNU shit on Linux and rely on more portable behaviour if you don't have GNU. Or you use muslc which doesn't pull as much crap. You can #ifdef that too.
I think it seems you want contradictory things. On one hand you claim that portable programs are desirable, on the other you say that you shouldn't rely on OS specific behaviour.
All behaviour is OS specific and outside of very trivial programs I challenge you to find an application that does not rely on #ifdefs, OS specific behaviour or duplicating code while also being portable.
Portability is not what I'd consider the utmost goal of software engineering, that would be solving the problem. Then comes maintainability. Portability is something at the end of a fairly long list.
As an engineer yes I want to solve practical problems with a computer, but I also don’t want to dictate (within reason) which OS the user must use. For example, if one of potential users of my software has a really advanced FreeBSD or OpenBSD setup and they can compile link and package my software, it would enable them to keep the advantages of their setup, and my software would make their advanced setup even more useful, like compound return on investment. Another advantage of this approach is that by not dictating the platform, it makes the user more productive and saves their time. People just want to get a task done and solve a problem, and respecting their time should be one of the programmer’s priorities.
Additionally I feel like it should be mentioned that even when POSIX and UNIX was a thing, programs had to include #ifdefs because target platforms wouldn't support X or didn't support Y in the same way as another platform. POSIX may have been designed to help against that but people still had to port their software a lot, with lots of #ifdefs and runtime shims.
As long as you have a well defined portability layer, it doesn't really matter if it uses #ifdef or separate files (actually SQLite can be embedded as a single file, so it matters, but still). The important point of Spencer's paper was that portability shouldn't be a second thought. In fact it also mentions how to use #ifdef, not just when not to use it.
Sounds like a lot of stuff like this has accumulated. Your dedication to backwards compatibility (and testing) is always very impressive, but don't you ever get the urge to do a parallel "SQLite Next" effort as it were? Kind of like python had the 2/3 years.
https://news.ycombinator.com/item?id=15648280 (157 comments)
And the relevant commit (timestamp 2017-10-27):
https://sqlite.org/src4/artifact/56683d66cbd41c2e
> All development work on SQLite4 has ended. The experiment has concluded.
> Lessons learned from SQLite4 have been folded into SQLite3 which continues to be actively maintained and developed. This repository exists as an historical record. There are no plans at this time to resume development of SQLite4.
This LWN article has a great explanation of all the behaviors: https://lwn.net/Articles/586904/
[1] Effectively identical to the Linux extension/POSIX proposal except that (1) they don't support ranges, (2) don't contend with POSIX locks (they do on real BSDs but not Linux), and (3) BSD flock won't work across NFS.
Glibc work won’t fix (e.g.) the BSDs.