3

Possible Duplicate:
where should “include” be put in C++

Obviously, there are two "schools of thought" as to whether to put #include directives into C++ header files (or, as an alternative, put #include only into cpp files). Some people say it's ok, others say it only causes problems. Does anybody know whether this discussion has reached a conclusion what is to be preferred?

Community
  • 1
  • 1
JohnB
  • 13,315
  • 4
  • 38
  • 65
  • 1
    http://stackoverflow.com/questions/2297567/where-should-include-be-put-in-c – chris Sep 23 '12 at 18:31
  • http://stackoverflow.com/questions/9906402/should-one-use-forward-declarations-instead-of-includes-wherever-possible/9906429#9906429 – Luchian Grigore Sep 23 '12 at 18:31
  • @chris: I'm not sure whether I find the answer there. "As a rule, put your includes in the .cpp files when you can, and only in the .h files when that is not possible." It will be always possible to put the include in the cpp, I guess. – JohnB Sep 23 '12 at 18:33
  • As long as you properly create your include guards, you can safely include any header anywhere, including other headers. –  Sep 23 '12 at 18:33
  • But it is not always possible to omit the include in another header. – juanchopanza Sep 23 '12 at 18:34

5 Answers5

6

I am not aware of any schools of thoughts concerning this. Put them in the header when they are needed there, otherwise forward declare and put them in the .cpp files that require them. There is no benefit in including headers where they are not needed.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • I'll try to find the reference again, but I'm not sure that I will be successful with that. – JohnB Sep 23 '12 at 18:35
3

What I found effective is following a few simple rules:

  • Headers shall be self-sufficient, i.e., they shall declare classes they need names for and include headers for any definition they use.
  • Headers should minimize dependencies as much as possible without violation the previous point.

Getting the first point rught is fairly easy: Include the header first thing from the source implementing what it declares. Getting the second point exactly right isn't trivial, though, and I think it requires tool support to get it exactly right. However, a few unnecessary dependencies generally aren't that bad.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 1
    Re *However, a few unnecessary dependencies generally aren't that bad.* They certainly can be bad. GNU's standard library included a lot of extra stuff up until 4.3. Code that implicitly required the capabilities of `` but only included `` would compile just fine with pre-4.3 releases of the standard library because the header `` had a superfluous include include of ``. The code didn't compile upon transition to 4.3 because that release got rid of a lot of those superfluous includes in the standard library. – David Hammen Sep 23 '12 at 18:55
  • The unnecessary dependencies are a result of clumping unrelated things into one header file. When you include a header, you get everything in that header. Everything in that header is not the exact set of dependencies that you actually need from that header. And that header includes other headers, and also gets more from them than it strictly needs, and so on. The only way to fight this in these preprocessor languages is to design clever, fine-grained headers. – Kaz Sep 23 '12 at 19:00
  • @DavidHammen: I agree with your statement and I consider it important to only include (and make available) what is necessary. Without a tool detecting unnecessary headers it is, however, nearly impossible to get it exactly right. Unfortunately, creating a tool for detecting if exactly the right headers are included is non-trivial, see e.g. [Google's header checker](http://code.google.com/p/include-what-you-use/source/browse/trunk/README.txt). – Dietmar Kühl Sep 23 '12 at 19:23
  • @DietmarKühl: I agree with all of that. My rules: #1: A header file should never include another header whose functionality is orthogonal to the header in question. (Don't #include something just because 2 of the 5 source files that implement the header need that other header.) #2: Use forward declarations instead of header inclusion if at all possible. #3: Include the header files that define the objects that the header code in question pokes into. #4: Think of moving that header code that does poke inside other objects to some source file. One last thing: +1 for your answer. – David Hammen Sep 24 '12 at 09:17
2

As a rule of thumb, you don't include the headers in a header as long as full definition of them is necessary there. Most of the time you play around with pointers of classes in a header file so it's just fine to forward declare them there.

rgngl
  • 5,353
  • 3
  • 30
  • 34
1

These are not schools of thought so much as religions. In reality, both approaches have their advantages and disadvantages, and there are certain practices to be followed for either approach to be successful. But only one of these approaches will "scale" to large projects.

The advantage of not including headers inside headers is faster compilation. However, this advantage does not come from headers being read only once, because even if you include headers inside headers, smart compilers can work that out. The speed advantage comes from the fact that you include only those headers which are strictly necessary for a given source file. Another advantage is that if we look at a source file, we can see exactly what its dependencies are: the flat list of header files gives that to us plainly.

However, this practice is hard to maintain, especially in large projects with many programmers. It's quite an inconvenience when you want to use module foo, but you cannot just #include "foo.h": you need to include 35 other headers.

What ends up happening is this: programmers are not going to waste their time discovering the exact, minimal set of headers that they need just to add module foo. To save time, they will go to some example source file similar to the one they are working on, and cut and paste all of the #include directives. Then they will try compiling it, and if it doesn't build, then they will cut and paste more #include directives from yet elsewhere, and repeat that until it works.

The net result is that, little by little, you lose the advantage of faster compiling, because your files are now including unnecessary headers. Moreover, the list of #include directives no longer shows the true dependencies. Moreover, when you do incremental compiles now, you compile more than is necessary due to these false dependencies.

Once every source file includes nearly every header, you might as well have a big everything.h which includes all the headers, and then #include "everything.h" in every source file.

So this practice of including just specific headers is best left to small projects that are carefully maintained by a handful of developers who have plenty of time to maintain the ethic of minimal include dependencies by hand, or write tools to hunt down unnecessary #include directives.

Kaz
  • 55,781
  • 9
  • 100
  • 149
  • 2
    The advantage of not including unnecessary headers in not only faster compilation. Dependency reduction is a very important factor. Why couple things that need not be coupled? – juanchopanza Sep 23 '12 at 18:41
  • Yes, and dependency reduction is achieved automatically by headers which include headers, not by manually including headers. You have the headers include the headers, and have the "include guards" in all headers, and then the compiler will always include just the transitive closure of the exact dependencies on each compile, while avoiding reading any header file twice. – Kaz Sep 23 '12 at 18:52
  • No, you cannot remove dependencies like that. A header that includes another, even if it does so indirectly, has a dependency on it. Include guards have nothing to do with it. – juanchopanza Sep 23 '12 at 18:57
  • Sorry, I cannot figure out what you're talking about. – Kaz Sep 23 '12 at 18:58
1

I think the issue was settle a long time ago: headers should be self-contained (that is should not depend on the user to have included other headers before -- that aspect is settle for so long that some aren't even aware there was a debate on this, but your put includes only in .cpp seems to hint at this) but minimal (i.e. should not include definitions when a declaration would be enough for self-containment).

The reason for self-containment is maintenance: should an header be modified and now depend on something new, you'd have to track all the place it is used to include the new dependency. BTW, the standard trick to ensure self-containment is to include the header providing the declarations for things defined in a .cpp first in the .cpp.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143