5 ms·
I know what they are for and don’t need instruction on that, thank you very much. I also know that #ifdefs are a bad practice with many pitfalls so their use s
by Annatar 8y ago
I know what they are for and don’t need instruction on that, thank you very much.
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?
- zaarn 8y agoUsing #ifdefs to get more out of certain architectures or working around quirks of a platform is definitely not something I'd consider bad practice. 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!)
- Annatar 8y agoThey are not a bad practice if their use is kept to a minimum, and if the #ifdef in question is picked out thoughtfully. 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.
- zaarn 8y agoThen what is the alternative where I don't loose good integration into OS capabilities while also being portable and not bloating the code?
- Annatar 8y agoWhere POSIX or XPG6 are insufficient, use core functions from libc, having verified that they exist on all OS targets and that they behave the same, and build the required functionality on top of those.
- zaarn 8y agoBut then you would not be able to, for example, take advantage of FreeBSD's pledge when available or SELinux to protect your application and the user. 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.
- Annatar 8y agoYes you wouldn't be able to take advantage of OS specific features, and you'd have to write platform agnostic code on top of what you do have, but that's the price to pay for portability. 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.
- JdeBP 8y ago* Henry Spencer and Geoff Collyer (1992). "#ifdef Considered Harmful, or Portability Experience With C News". USENIX ’92 Proceedings. pp 185-197. https://usenix.org/legacy/publications/library/proceedings/sa92/spencer.pdf https://usenix.org/legacy/publications/library/proceedings/s...
- Annatar 8y agoYes, that’s the document! Thanks so much for locating it, really appreciate it!
- bonzini 8y agoBest practices in portability have evolved since the 90s. I understand that portable C from that time was a nightmare, but things have changed a lot. 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.