tags:

views:

291

answers:

7

I talked to my instructor the other day and asked him this question. He told me that I could go for smaller projects, but I'm starting a chess program and I was wondering what Stack Overflow thinks about this issue. Should I include all headers into one file, or separate them?

A: 

It's a bad idea in general, because you can have dependencies you'll not be able to solve in this case.

But it's usually a good idea to create a header file with all base headers you are using from different libraries or your own header (with structs and data types definitions).

Elalfer
A: 

There's no one-way-fits-all solution. Arrange your headers how it makes the most sense. 90+% of the time, that means that each module includes only the headers it needs. However, some programs have little isolation of the data structures between modules—that could mean that there is a use for

#include "alltheheaders.h"
wallyk
+13  A: 

Normally, you want separate headers.

Including more than necessary does a few potentially bad things.

  1. This is single greatest cause of slow compile times. Unnecessary inclusion of extra headers slows down compilation, since each source file has to worry about more info than it needs. It starts as a small problem, and before you know it hundreds of developers are wasting dozens to hundreds of hours each because the problem got too far out of hand to fix. Even though you're working on small problems, it's important to understand proper separation of headers - it's easy to get right the first time but very hard to fix later if you ignore it.

  2. You lose the ability (depending on compiler/IDE) to correctly handle dependencies, and wind up building more information than you need to build.

  3. You lose maintainability. It's more difficult to maintain software when you have large, single files, than when you have lots of small, concise files.

  4. You make the code more difficult to understand, hence more prone to bugs. By having everything in one file, it's easier to get "lost" in the huge header.

Reed Copsey
In addition, selectively including headers adds a component of self-moderation: as you go to add new functionality to a file, if the code you're using would require adding another header include, you can consider whether it actually fits in that file or would be better of implemented elsewhere.
Amber
Very true, Dav.
Reed Copsey
and it interfers with precompiled headers, as the single headerfile changes whenever you change any header file. This means it has to be precompiled again (see point 1 of Reed).
Tobias Langner
I edited #1 based on experience with work projects and *lots* of time spent analyzing build issues.
280Z28
My impression is that (2)'s a bigger waste of programmer time than (1), actually. I rarely sit around waiting for a full build of a significant-sized project. I frequently sit around waiting for partial builds. Including stuff you don't use adds a chunk of time, sure, but re-building object files which don't need it adds *multiples* to the incremental build time. So touch any header, and in effect you need a full rebuild. The alternative is to deliberately get the dependencies wrong, and rely on remembering what really needs rebuilding. Either way: aargh!
Steve Jessop
+2  A: 

There are some times when this practice is useful:

  1. Pre-compiled header files with code that really doesn't change that often.

  2. APIs

Matt
With the hardware available today, and possibly with my smaller sized programs and modules, I haven't felt the need for pre-compiled headers in a long time.
mjv
Recently I did a relatively small five module project using MFC on Microsoft Visual studio 2008. The compile is so bogged down with MFC object framework that precompiled headers are faster than not. Still, I clocked its read of the precompiled data as several seconds.
wallyk
@mjv: Our main product's solution contains > 350.000 LOC. Even with dual quad-core machines, 16 GB RAM and striped RAID disks we struggle to keep the compile time below 10 minutes for a debug build. In release builds the global optimization linking takes another 15 minutes. Without precompiled headers, we'd sit here for hours I think.
Sebastian
A: 

For a smaller project you'll never notice the difference. However, once your project reaches significant scale, stick by the old adage, "Only reference headers in files that are directly using them". If you have myclass.cpp and myclass.h, and myclass.h doesn't directly need a specific header, reference it in the cpp.

This may take more time, but best practice is always worth the time.

Norla
A: 

I just want to add that, yes this is normally a bad idea, but it can be useful on occasion. Never for entire projects though.

For example, I recently wrote a utility to perform a stack dump on windows. There were 4 common headers I was going to include, so I made (in a detail folder, a convention I stole form boost use) a windows.hpp, which included those four. The implementations could then use that header to easily get the necessary functions.

While it might not carry the same weight as a mega-includes-480-headers header, it was a grouping of a handful of common headers, and it was quite helpful. the key thing here is it was a small collection of related headers, used in a portion of the code.

GMan
A: 

You should keep the number of headers included in any source (*.cpp, *.cc etc.) file to the minimum required to compile that file. Including extra headers will increase compile times. You should also try and reduce the number of includes in your headers - you can do this by forward declaring classes rather than including their headers.

e.g. The following code has an unnecessary include in the header

Example.hh

#include "SomeClass.hh"

void SomeFunction(SomeClass const& obj);

Example.cc

#include "Example.hh"

void SomeFunction(SomeClass const& obj)
{
   // code here
}

It can be written as to move the include from the header to the source file

Example.hh

class SomeClass;

void SomeFunction(SomeClass const& obj);

Example.cc

#include "Example.hh"
#include "SomeClass.hh"

void SomeFunction(SomeClass const& obj)
{
   // code here
}
Andrew Burrows