5 ms·
The more modern gcc handling is with "#pragma once": http://en.wikipedia.org/wiki/Pragma_once http://en.wikipedia.org/wiki/Pragma_once His comments on include
by apaprocki 15y ago
The more modern gcc handling is with "#pragma once":
http://en.wikipedia.org/wiki/Pragma_once 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."
- luriel 15y ago> 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. 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 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 http://man.cat-v.org/plan_9/2/intro
- apaprocki 15y agoWell it stands to reason that the Plan 9 code would work that way if Rob Pike made the comment. I'm just wondering if anyone else found this way of coding attractive. Everything I've seen points to "no".
- 4ad 15y agoDennis Ritchie, creator of C? Ken Thompson, creator of Unix?
- catwell 15y agoThere is even a relatively popular piece of software dedicated to helping developers use this style: http://code.google.com/p/include-what-you-use/ http://code.google.com/p/include-what-you-use/
- apaprocki 15y agoThat is not the stated purpose of the tool (to write code in the aforementioned style): "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.
- charolastrauno 15y agoThat's not true - you can't forward-declare types used in class member variables for instance.
- keithflower 15y agoOur experiences don't match. Avoiding nested includes has been a part of the rigorous and useful standards of a lot of important, mission-critical, large-scale projects, and is something I try to enforce in my own code. 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 http://sunland.gsfc.nasa.gov/info/cstyle.html European Molecular Biology Open Software Suite (EMBOSS) http://emboss.sourceforge.net/developers/c-standards_new.html http://emboss.sourceforge.net/developers/c-standards_new.htm... Atacama Large Millimeter Array (astronomy): http://www.alma.nrao.edu/development/computing/docs/joint/0009/2001-02-28.pdf 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 http://staff.washington.edu/jon/cnts/impl.pdf
- tptacek 15y agoI take your point, but I'm not sure you're really taking his. As another data point, I just did a find/xargs-grep across my "~/codebase/3p" tree, which has ~5500 .h files for projects ranging from MongoDB to Ruby and Python to OpenSSL to valgrind. Virtually all of them have nested includes. Many of them are components of mission-critical software. He's right; nested includes are a modern C idiom.
- keithflower 15y ago> 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'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/ http://www.python.org/dev/peps/pep-0020/ /irrelevant quote
- apaprocki 15y agoTo be fair here, NASA does say to avoid nesting headers. But then it follows up with this ridiculous statement: 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.
- nitrogen 15y agoThe more modern gcc handling is with "#pragma once": 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.
- apaprocki 15y agoWe use both internally, actually. GNU gcc/g++ and IBM xlc/xlC all support doing this: #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.