1

Let's say I have a header file called foo.h, and it includes another header, bar.h.

I also have a header file called xyz.h. It requires foo.h and bar.h, although foo.h and bar.h have nothing to do with each other, so I would feel weird to just include foo.h (which still compiles since it includes bar.h...

So, foo.h includes bar.h, bar.h doesn't include foo.h, but xyz.h does include foo.h and bar.h. Is this bad practice? Is there any reason why I shouldn't? Why am I able to do this?

David Makogon
  • 69,407
  • 21
  • 141
  • 189
  • 2
    It's common practice. You don't always know what other header files a header includes, so you include all the ones you need. [#include guards](https://en.wikipedia.org/wiki/Include_guard) prevent problems if the same header is included twice. – Barmar Aug 21 '16 at 04:12
  • 3
    Every header file should include *all* the headers that *it* needs ignoring whether or not they might get incidentally included through another header (because that can change). – Galik Aug 21 '16 at 04:13
  • Look up 'Include What You Use' via a search engine. It should bring up http://include-what-you-use.org/ and https://github.com/include-what-you-use/include-what-you-use and other references. – Jonathan Leffler Aug 21 '16 at 05:29
  • @JonathanLeffler That looks really useful, thanks for the link! – K.K. Slider Aug 21 '16 at 06:01
  • "...foo.h, and it includes another header, bar.h. ... ...although foo.h and bar.h have nothing to do with each other." - **This is weird.** If `foo.h` and `bar.h` have nothing to do with each other, why are you including `bar.h` in `foo.h`? –  Aug 21 '16 at 07:40
  • @smlq Let me give an example from something I'm working on. Let's say I have a "Shader" class for OpenGL, and it includes the GLEW (extension wrangler) header. I also have a "Renderer" class which acts as a sprite batch. It must use `shader.h` *and* `glew.h`, but `shader.h` already includes it so technically I could just get away with only including it. Would that be bad practice, or do people often do similar things? – K.K. Slider Aug 21 '16 at 19:39

1 Answers1

2

Each header should be self-contained. It should include all other headers it needs and have include guards.

Suppose that the header was not self contained. Then if you wish to use that header in a different client, then the new client wouldn't even compile unless you found and pulled the need other headers.

There are also can be rare case when header file can be not self-contained, e.g. checks Google's code style for details.

Most of compilers support options for include dependency investigation. These options and other tools are discussed in this question.

Community
  • 1
  • 1
Nikita
  • 6,270
  • 2
  • 24
  • 37
  • What you say in the first paragraph is true — it is often termed 'self-contained and idempotent'. However, this question is asking "what does it mean to be self-contained" when you get multiple headers involved. The issue is that a header A.h can be self-contained because it includes another header B.h, which in turn includes C.h, and C.h defines something that A.h uses. While B.h continues to need C.h, A.h is self-contained in the sense that it will work, but if B.h changes so that it no longer needs C.h but A.h does still need C.h, then A.h is no longer self-contained — because B.h changed. – Jonathan Leffler Aug 21 '16 at 05:55
  • @JonathanLeffler If `A.h` uses something that is defined in `C.h` than it should includes `C.h` or have a forward-declaration for used stuff. I understand it as "self-contained" header. – Nikita Aug 21 '16 at 06:18
  • 1
    I understand; I agree. But how do you demonstrate that A.h is not properly self-contained while B.h still includes C.h? See [Should I use `#include` in headers?](http://stackoverflow.com/questions/1804486) for the C programmer's view on things, and some fairly effective ways of ensuring self-containment. But the 'fairly effective way' is vulnerable to the A.h, B.h, C.h scenario outlined above — and there isn't a trivial way to avoid that. See http://Include-What-You-Use.org/ etc. – Jonathan Leffler Aug 21 '16 at 06:19
  • @JonathanLeffler Yes, it' often a bit tricky to understand dependency without automatic tools. – Nikita Aug 21 '16 at 06:36