19

Should I include every header even if it was included before? Or maybe I should avoid it when I can? For example. If I use std::string and std::vector in some file. If <string> included <vector> should I include only <string> or <string> and <vector>?

Niall
  • 30,036
  • 10
  • 99
  • 142
peter55555
  • 1,413
  • 1
  • 19
  • 36

2 Answers2

36

TLDR

If you use it, include it.

The longer version...

If you use a header related entity (e.g. some type) in a file, you should include the related header for it. Don't rely on headers to include each other. If you use it, include it.

The C++ standard library doesn't mandate inclusion of <string> in <vector> nor vice-versa. Trying to make use of functionality like this would limit the code to a specific implementation. In general, the standard library headers may or may not include other headers (or their own internal headers) in an unspecified order or manner. One notable exception is <initializer_list> which is required to be included in a few of the other standard headers. Changes to this unspecified order or manner can also happen, thus breaking previously compiling code with the updated compiler or an updated standard library implementation (this has been known to happen).

Also consider that if the header file is the definition for the class, then it should include what is required for the definition of that class. The associated .cpp should include its associated .h and the remaining files required to implement the class. Don't need it, don't include it; don't include more than needed (llvm style guide). One exception here is templates (that don't have an associated .cpp); this exception would apply to other header only implementations.

It is noted that maintenance of the include what you use can be difficult in the long run; thus it makes sense that it is important in the beginning of the coding cycle to include what is required for the interface; and then again to check the includes with any reasonable change that is made to the code.

There seems to be some progress w.r.t. tools in this regard, such as the iwyu project, that uses the clang tool chain and seems to have support for msvc as well.

One counter example would be if the reason for the header is to include other headers, then maybe, but even then I would be very careful - make sure it is clearly defined what it includes. An example of this could be a precompiled header.

Niall
  • 30,036
  • 10
  • 99
  • 142
  • 9
    You may also want to mention that for one's own C++ files, the interface in the `.h` file should include only the headers used for the interface, but the implementation in the `.cpp` file would contain everything additionally required for the implementation. – Edward Oct 28 '14 at 15:03
  • 3
    I agree with this sentiment in theory. Unfortunately, it is fairly difficult to detect it if you slip up. – dlf Oct 28 '14 at 15:10
  • @dlf. This is true. I've also fallen afoul of the discipline as well. I'm not sure how some of the tooling is changing to support checking these things. Sometimes I just need to go back and audit my own code. – Niall Oct 28 '14 at 15:12
  • 1
    In general standard library headers may include each other in unspecified ways and you shouldn't rely on it. There are specific cases where a header is required to include another: a number of headers are required to include ``, for instance. – T.C. Oct 28 '14 at 15:58
  • To add to the last paragraph: If classA uses classB (e.g. as result type of a method) I'd always prefer to `#include "classB"` only in `classA.cpp`, not in `classA.h` if possible (a `class classB;` may suffice there) – Hagen von Eitzen Oct 28 '14 at 23:13
  • 1
    It should be noted that the problem you describe is more pronounced with templates: Templates have to include their implementation, and, consequently the headers required for it. That is, with a template you can't follow the rule of separating interface and implementation includes that @Edward pointed out. However, if your headers only ever include stuff they need for the interface, that set of includes is usually relatively small, and it shrinks seldomly. So it's generally safe to only include a set of headers that pull in everything that's required if those headers do not define templates. – cmaster - reinstate monica Nov 02 '14 at 08:07
8

Generally, you should treat header dependencies as part of implementation, not as part of interface.

You should not rely on headers including other headers. If your class needs to use a std::vector, include <vector>; if you need std::string, include <string>. Otherwise you set yourself up for unexpected breakdowns when headers that used to include a file would suddenly stop including it, because they no longer need it.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523