Good stuff, if slightly self-contradictory in places. The header file named after the source should be included first (to catch errors in the header) and the header file defining various macros should be included first (as otherwise it doesn't work).<p>The detect-missing-includes-in-header is better handled by a separate compilation job which compiles the header by itself as it if was C++, `clang -xc foo.h`, solely for the purpose of catching that error. Then the include your own header first rule no longer matters.<p>Forward declarations have a cost which the article misses. When the thing in question changes, your compiler no longer warns you when the forward declaration is out of sync with the real thing, and the linker diagnostics are usually less comprehensible. Also it's a nuisance to update all the forward declarations. An <iosfwd> style header, included at the top of the <ios> header, gives ~99% of the compile time advantage of forward declarations with none of the failure modes and usually less typing in the caller.
><i>We’re stuck with C++, at least for another console generation.</i><p>That was 14 years ago. C++ is not going anywhere, whether 1, 2, or 10 "console generations" ahead.
A great way to handle context-specific headers: common path rooted in context-specific directories coupled with include path management.<p>Useful for platform- and architecture-specific code but can be used for anything really. Anything you want to parameterize and compile conditionally.<p>Instead of this mess:<p><pre><code> #if APP_LINUX
#include <app/linux.h>
#elif APP_BSD
#include <app/bsd.h>
#elif APP_MACOS
#include <app/macos.h>
#else
#error "Unsupported platform"
#endif
</code></pre>
Organize things like this instead:<p><pre><code> linux/include/app/platform.h
bsd/include/app/platform.h
macos/include/app/platform.h
</code></pre>
Then in the makefile:<p><pre><code> # Detect it somehow
# or have user provide it
PLATFORM ?= $(shell uname -s)
cc -I include -I $(PLATFORM)/include
</code></pre>
Then in the source code:<p><pre><code> #include <app/platform.h></code></pre>
In modern C++ there will be modules (C++20). Even std will be available as a module (C++23). This will likely bring down compile times massively. But so far the only compiler with support for this today is MSVC.
I no longer use header files when I can help it. They haven't made sense since 1980. I have a Python script that reads my C++ source and writes all the headers for me. C++ is so much nicer to write when you don't have to do the compiler's job for it.<p>Modules are supposed to be coming soon, and then I won't even need the script anymore.
this is still lacking a lot of important rules (group by nature of dependency, sort alphabetically within a group, sort groups per dependency level, use angle brackets for third-party only) and is still only barely scratching the surface of C++ file organization.