3 ms·
Generally speaking all this stuff is good, but I'd add that his note on Include files is dated and I wouldn't recommend it anymore. Any compiler worth half its
by DSMan195276 10y ago
Generally speaking all this stuff is good, but I'd add that his note on Include files is dated and I wouldn't recommend it anymore. Any compiler worth half its salt at this point will recognize the include guard pattern and not parse though include'd files multiple times, so the worry about wasting tons of time due to that pattern is largely gone.
The big problem with what he's suggesting is that if you're designing a fairly big system with lots of decently small headers (Which is generally good - simple headers with easy-to-read APIs are good), you'll end-up with a crazy number of include's in every file - and if you change something to use a new dependency, then you'll have to change every location it is include'd in as well. There is something to be said about avoiding things like circular dependencies, but this requirement really doesn't make it any harder for that to happen, and just creates more problems and annoyances - it is not a very scalable solution.
If you look at the Linux Kernel source (Which is arguably one of the largest and most successful C programs) each source file has at around 10 to 30 include's at the top (Or more in some cases), and that's with the headers including other headers. If instead Linux had taken the approach Rob is recommending, that number would probably be a magnitude larger and extremely hard to manage even if they combined a bunch of the headers they have together to reduce the total number (Which, again, I would consider a huge anti-pattern).
- adrianratnapala 10y agoI think I agree that includes-within-includes are probably a necessity. But I am not that it allows things to be broken into "simple headers with easy-to-read APIs". That is true for headers that are small and only #include system headers and other basic dependencies. But if your own code has a nest of interelated headers, then a single big header file is probably easier to read.
- DSMan195276 10y agoWell I mean, perhaps I should have clarified, "simple headers with easy-to-read APIs" has to be looked at on a case-by-case basis and what makes sense. I would argue that as a general rule it is what you should aim for if possible (And I find it is possible in a lot of cases, and that if it's not things may be getting a bit too interconnected), but you're right that there are situations where things are a bit too complicated to split-up easily so a single header for multiple things makes sense. I think that if you're constantly in that situation though, you should reevaluate how you're designing your components and headers.
- moogly 10y agoDoesn't every compiler support '#pragma once' these days too, making include guards largely pointless (and like most copy/paste patterns, error-prone) boilerplate?
- BudVVeezer 10y agoYes and no. Many compilers support #pragma once, but whether your build environment handles it is another matter. Having your headers on network drives, or having symlinks to your headers, etc can cause issues with #pragma once handling (depending on the implementation) that can often be hard to track down, especially if building with multiple compilers. Include header guards do not have these issues.
- moogly 10y agoCool, thanks for the clarification!
- gonzo 10y ago"Using Unix is the computing equivalent of listening only to music by David Cassidy." -- Rob Pike