tags:

views:

304

answers:

6

I have a question regarding "best-practice" when including headers.

Obviously include guards protect us from having multiple includes in a header or source file, so my question is whether you find it beneficial to #include all of the needed headers in a header or source file, even if one of the headers included already contains one of the other includes. The reasoning for this would be so that the reader could see everything needed for the file, rather than hunting through other headers.

Ex: Assume include guards are used:

// Header titled foo.h
#include "blah.h"
//....

.

// Header titled bar.h that needs blah.h and foo.h
#include "foo.h"
#include "blah.h" // Unnecessary, but tells reader that bar needs blah

Also, if a header is not needed in the header file, but is needed in it's related source file, do you put it in the header or the source?

A: 

Including everything upfront in headers in C++ can cause compile times to explode

Better to encapsulate and forward declare as much as possible. The forward declarations provide enough hints to what is required to use the class. Its quite acceptable to have standard includes in there though (especially templates as they cannot be forward declared).

Stuart
The asker wanted to know if include dependencies of `#include`d files as `#includes`, not how to use includes.
pavpanchekha
Also true: "C++ can cause compile times to explode"
bk1e
And I quote: "Also, if a header is not needed in the header file, but is needed in it's related source file, do you put it in the header or the source?"
Stuart
+7  A: 
Beta
On compiling dependencies, I like Sutter's puzzle: http://www.gotw.ca/gotw/007.htm
Matthieu M.
+3  A: 

The basic rule is, #include any headers that you actually use in your code. So, if we're talking:

// foo.h
#include "utilities.h"
using util::foobar;

void func() {
    foobar();
}

// bar.h
#include "foo.h"
#include "utilities.h"
using util::florg;

int main() {
    florg();
    func();
}

Where bar.h uses tools from the header included twice, then you should #include it, even if you don't necessarily have to. On the other hand, if bar.h doesn't need any functions from utilities.h, then even though foo.h includes it, don't #include it.

pavpanchekha
+3  A: 

The header for a source file should define the interface that the users of the code need to use it accurately. It should contain all that they need to use the interface, but nothing extra. If they need the facility provided by xyz.cpp, then all that is required by the user is #include "xyz.h".

How 'xyz.h' provides that functionality is largely up to the implementer of 'xyz.h'. If it requires facilities that can only be specified by including a specific header, then 'xyz.h' should include that other header. If it can avoid including a specific header (by forward definition or any other clean means), it should do so.

In the example, my coding would probably depend on whether the 'foo.h' header was under the control of the same project as the 'blah.h' header. If so, then I probably would not make the explicit second include; if not, I might include it. However, the statements above should be forcing me to say "yes, include 'foo.h' just in case".

In my defense, I believe the C++ standard allows the inclusion of any one of the C++ headers to include others - as required by the implementation; this could be regarded as similar. The problem is that if you include just 'bar.h' and yet use features from 'blah.h', then when 'bar.h' is modified because its code no longer needs 'blah.h', then the user's code that used to compile (by accident) now fails.

However, if the user was accessing 'blah.h' facilities directly, then the user should have included 'blah.h' directly. The revised interface to the code in 'bar.h' does not need 'blah.h' any more, so any code that was using just the interface to 'bar.h' should be fine still. But if the code was using 'blah.h' too, then it should have been including it directly.

I suspect the Law of Demeter also should be considered - or could be viewed as influencing this. Basically, 'bar.h' should include the headers that are needed to make it work, whether directly or indirectly - and the consumers of 'bar.h' should not need to worry much about it.

To answer the last question: clearly, headers needed by the implementation but not needed by the interface should only be included in the implementation source code and absolutely not in the header. What the implementation uses is irrelevant to the user and compilation efficiency and information hiding both demand that the header only expose the minimum necessary information to the users of the header.

Jonathan Leffler
A: 

My Rules for header files are:

Rule #1

In the header file only #include class's that are members or base classes of your class.
If your class has pointers or references used forward declarations.

--Plop.h
#include "Base.h"
#include "Stop.h"
#include <string>

class Plat;
class Clone;

class Plop: public Base
{
    int           x;
    Stop          stop;
    Plat&         plat;
    Clone*        clone;
    std::string   name;
};

Caviat: If your define members in the header file (example template) then you may need to include Plat and Clone (but only do so if absolutely required).

Rule #2

In the source put header files from most specific to least specific order.
But don't include anything you do not explicitly need too.

So in this case you will inlcude:

  • Plop.h (The most specific).
  • Clone.h/Plat.h (Used directly in the class)
  • C++ header files (Clone and Plat may depend on these)
  • C header files

The argument here is that if Clone.h needs map (and Plop needs map) and you put the C++ header files closer to the top of the list then you hide the fact that Clone.h needs map thus you may not add it inside Clone.h.

Rule #3

Always use header guards

#ifndef  <NAMESPACE1>_<NAMESPACE2>_<CLASSNAME>_H
#define  <NAMESPACE1>_<NAMESPACE2>_<CLASSNAME>_H

// Stuff

#endif

PS: I am not suggesting using multiple nested namespaces. I am just demonstrating how I do if I do it. I normal put everything (apart from main) in a namespace. Nesting would depend on situation.

Rule #4

Avoid the using declaration.
Except for the current scope of the class I am working on:

-- Stop.h
#ifndef THORSANVIL_XXXXX_STOP_H
#define THORSANVIL_XXXXX_STOP_H

namespace ThorsAnvil
{
    namespace XXXXX
    {

class Stop
{
};

     } // end namespace XXXX
} // end namespace ThorsAnvil

#endif

-- Stop.cpp
#include "Stop.h"
using namespace ThorsAnvil:XXXXX;
Martin York
Arguably, I use exactly the inverse of Rule #2. The reasoning is that I don't want a 'more specific' header to accidentally pollute the context in which a 'less specific' header is included.
Matthieu M.
I disagree with your reasons, but there is an ongoing debate on the subject (which will probably never be resolved) and I concede that it is an alternative appropriate method. My main rule #0 is just be consistent.
Martin York
A: 

My comments might not be a direct answer to your question but useful.

IOD/IOP encourages that put less headers in INTERFACE headers as possible, the main benefits to do so:

  1. less dependencies;
  2. smaller link-time symbols scope;
  3. faster compiling;
  4. smaller size of final executables if header contains static C-style function definitions etc.

per IOD/IOP, should interfaces only be put in .h/.hxx headers. include headers in your .c/.cpp instead.

EffoStaff Effo