Question

I am used to putting header guards around my objects like:

#ifndef SOMETHING_H
#define SOMETHING_H

class Something {
...
}
#endif

but I have been given code where they also do:

#ifndef SOMETHING_H
#include "something.h"
#endif

for every include. Supposedly, this is better. Why? Is this redundant with guards around the object?

Was it helpful?

Solution

This is discussed in pretty good detail here:
http://c2.com/cgi/wiki?RedundantIncludeGuards

Here are the highlights:

  • Yes this is redundant, but for some compilers it may be faster because the compiler will avoid opening the header file if it doesn't need to.
  • "Good compilers make this idiom unnecessary. They notice the header is using the include-guard idiom (that is, that all non-comment code in the file is bracketed with the #ifndef). They store an internal table of header files and guard macros. Before opening any file they check the current value of the guard and then skip the entire file."
  • "Redundant guards have several drawbacks. They make include sections significantly harder to read. They are, well, redundant. They leak the guard name, which should be a secret implementation detail of the header. If, for example, someone renames the guard they might forget to update all the places where the guard name is assumed. Finally, they go wrong if anyone adds code outside of the guard. And of course, they are just a compile-time efficiency hack. Use only when all else fails."

OTHER TIPS

The thinking behind it is the preprocessor will not need to open the header file and read the contents to determine that that header has been previously included, thus saving some time during compilation. However, most compilers these days are already smart enough to spot multiple inclusions of the same file and ignore subsequent occurrences.

It's good to have this on header and class definition files, so that on compilation, if a file is referenced in a loop (a.cpp references a.h and b.cpp, and b.cpp also references a.h, a.h will not be read again) or other similar cases.

The case that worries me most about what looks like your question is that the same constant name is being defined in different files, and possibly preventing the compiler from seeing some necessary-to-see constants, classes, types, etc. as it will "believe" that the file was "already read".

Long story short, put different #ifndef constants in different files to prevent confusion.

The purpose of doing this is to save on compile time. When the compile sees #include "something.h", it has to go out and fetch the file. If it does that ten times and the last nine all basically amount to:

#if 0
...
#endif

then you're paying the cost of finding the file and fetching it from disk nine times for no real benefit. (Technically speaking, the compiler can pull tricks to try and reduce or eliminate this cost, but that's the idea behind it.)

For small programs, the saving probably aren't very significant, and there isn't much benefit to doing it. For large programs consisting of thousands of files, it isn't uncommon for compilation to take hours, and this trick can shave off substantial amounts of time. Personally, it's not something I would do until compilation time starts becoming a real issue, and like any optimization I would look carefully at where the real costs are before running around making a bunch of changes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top