3 ms·
> I have always been a fan of using module_os_arch.cpp Oh no, I found that to work very very poorly. It's an antipatterns because architectures change, and th
by knorker 7y ago
> I have always been a fan of using module_os_arch.cpp
Oh no, I found that to work very very poorly. It's an antipatterns because architectures change, and that you can't cover all architectures.
Not only for my own software (I've maintained portable open source for decades across many architectures), but also huge frustration when porting software to a new (for that software) architecture.
Examples:
The software should not care if it's "linux" or "freebsd", you care if getpwnam_r is the three or four argument version. When one OS changes (or admin tweaks it) to the POSIX compliant API by default, what do you do then?
OpenBSD is API wise close to FreeBSD. So now I should find all files named ._freebsd_. and make a copy to _openbsd_, forking the code, if I port to OpenBSD?
What about Debian kFreeBSD? You don't have all of these OSs, so just test features, not OS.
- jstimpfle 7y agoI think the general idea is simply that you don't use #ifdef but instead move the conditional compilation logic to the build script / build system. Of course you should group in files in a way that avoids redundancy. This is the way I'm going about it at least, even though I assume there might be complex situations where the boilerplate isn't warranted and it's better to put all the variants in a single file and use the preprocessor to determine which alternative to compile. Like you say in the end, test features (or maybe standards support), not too-specific things like OS or distribution.
- pjmlp 7y agoYep, this is something we can definitely agree on. :)
- knorker 7y ago> the general idea is simply that you don't use #ifdef but instead move the conditional compilation logic to the build script / build system. Yes, I entirely agree. But do NOT split it into what OS or architecture it is, like what I was replying to said.
- pjmlp 7y agoTry to debug a 10 level depth of nested #ifdef, across a 10000+ lines source code file, managed by unknown number of consulting companies paid by the tickets thought 20 years of company history without any kind of code review processes and you will get in love with such anti-patterns. Naturally one has to make the groupings in a way that makes sense, and the code organisation is not set in stone. Refactorings can and should be done when it makes sense to do so.
- knorker 7y ago> Try to debug a 10 level depth of nested #ifdef, across a 10000+ lines source code file My experience doing this is exactly why I'm saying do NOT split into OS and arch. Many times what should have "just worked" without even needing porting by anyone, turns into a multi thousand line refactoring just because of hard coded operating system names in the source code. Let's say you have your sound code in sound_linux.cc and sound_freebsd.cc (and sound_openbsd.cc, and...) and then 10 years from now freebsd switches to entirely using ALSA. Your code now breaks. If you'd instead done "sound_alsa.cc" and detected the ability to use ALSA at build time, then zero coding needs to be done. The one exception I think is Windows. It's uniform enough over time, and entirely different from everything else, that it does make sense to have sound_windows.cc. There are antipatterns other than foo_os_arch.cc, such as the one you point out (nested mess of #ifdefs in code), but that doesn't invalidate that module_os_arch isn't an antipattern. Because it is. Go (the language) does "list of OS names", and it's a complete mess. Syscalls that actually are the same are not in the std library, because they were split by OS name. Had they tested for features the implementation would have been the same. And this hurts all users of that language as a result.
- pjmlp 7y agoThat just reveals that the architecture design was wrong to start with. We need more developers reading books like " Large-Scale C++ Software Design". It is such an anti-pattern that C and C like C++ codebases are the only ones that go down the #ifdef spaghetti route, with large majority of everyone else using modules to isolate architecture dependences. So not sure about it being an anti-pattern when it is the architecture design pattern with winning votes.