Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The more modern gcc handling is with "#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."



Our 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

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


I 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.


> 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/

/irrelevant quote


To 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.


> 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

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


Well 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".


There is even a relatively popular piece of software dedicated to helping developers use this style: http://code.google.com/p/include-what-you-use/


That 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.


That's not true - you can't forward-declare types used in class member variables for instance.


Dennis Ritchie, creator of C? Ken Thompson, creator of Unix?


The 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.


We 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: