http://en.wikipedia.org/wiki/Pragma_once
His comments on include files are not the way the world has gone. In all my years writing C, I have never seen a C/C++ header which does not include the other headers it needs in order to compile cleanly.
He states: "Simple rule: include files should never include include files."
If you can find me one C project out there which has headers with zero #includes and forces each compilation unit including the header to include all the prerequisites needed for that header I would be genuinely interested. Even all OS header files include their pre-requisites and it is considered a bug if they do not do so. A more modern 21st century rule would be:
"Simple rule: include file order does not matter. Use include guards (or #pragma once) and always include only the prerequisites needed to cleanly compile and nothing more."
A whole OS does this: Plan 9 from Bell Labs :)
For details see the paper by Rob Pike: How to Use the Plan 9 C Compiler
http://doc.cat-v.org/plan_9/4th_edition/papers/comp
Also the Plan 9 libraries are much cleaner and leaner than those in 'modern' *nix systems, which makes keeping track of includes much easier: http://man.cat-v.org/plan_9/2/intro
"Include what you use" means this: for every symbol (type,
function variable, or macro) that you use in foo.cc, either
foo.cc or foo.h should #include a .h file that exports the
declaration of that symbol.
I agree 100% with that statement. According to the style, foo.h can never #include anything.There are numerous examples of projects which follow that recommendation. I'm told, for example, that the recommendation on the excellent Blender 3-D graphics system is to avoid nested includes. Other examples:
NASA: http://sunland.gsfc.nasa.gov/info/cstyle.html
European Molecular Biology Open Software Suite (EMBOSS) http://emboss.sourceforge.net/developers/c-standards_new.htm...
Atacama Large Millimeter Array (astronomy): http://www.alma.nrao.edu/development/computing/docs/joint/00...
Clinical Neutron Therapy System (for radiation oncology): http://staff.washington.edu/jon/cnts/impl.pdf
He's right; nested includes are a modern C idiom.
> He's right; nested includes are a modern C idiom.
No doubt they are found a lot. The request was for counterexamples. Fashion/style vs engineering practice assertions may be passing like ships on a nighttime C here.
>...for projects ranging from MongoDB to Ruby and Python...
Python....why, even Tim Peters asserts that "Flat is better than nested"...wink...
http://www.python.org/dev/peps/pep-0020/
/irrelevant quote
In extreme cases, where a large number of header files are
to be included in several different source files, it is
acceptable to put all common #includes in one include file.
I would not trust anything else the author of that guide writes. EMBOSS says not to nest. The Atacama code suggests not nesting but then says: To avoid nested includes, use #define wrappers as follows:
The last pdf states: This prevents including the same item more than once when
a .c file includes several .h files (we rejected
alternatives involving conditional compilation as too
complicated).
I guess it boils down to preference since the language allows you to do either, I just don't put a lot of stock in these style guides.I've considered switching to this, but in the interest of maximum hypothetical portability, I've decided to stick with the #ifndef include guard. I've just checked the C1X standard draft I have, and #pragma once is still not in the standard (6.10.6.1 in the version I have).
As for your other points, I agree with the notion that a header file should include its dependencies, but no more. I suppose my thinking on this is influenced by the dependency tracking of Linux package managers such as apt.
#if defined(... all the compilers above ...)
# define PRAGMA_ONCE _Pragma("once")
#else
# define PRAGMA_ONCE
#endif
Specifically, MSVC and HP cc/aCC do not support it. Oracle cc/CC does the #ifndef/#define detection and internally does something similar to what the pragma enables in other compilers.> The result is often thousands of needless lines of code passing through the lexical analyzer, which is (in good compilers) the most expensive phase.
If only...
The way that part is worded seems a bit confusing.
#ifndef some_header
#include some_header
#endif