3

I recently started working on a project where I came across this:

#include <string.h> // includes before include guards
#include "whatever.h"

#ifndef CLASSNAME_H // header guards
#define CLASSNAME_H
// The code
#endif

My question: Considering all (included) header files were written in that same style: Could this lead to problems (cyclic reference, etc.). And: Is there any (good) reason to do this?

pianoslum
  • 327
  • 3
  • 9
  • 1) Include guards are Good. 2) I would expect to see them only in a header, and I would expect them to wrap the *ENTIRE* header. 3) I would *not* use include guards with code. And I *dislike* including code in headers. 4) Your header can (and should) #include whatever it needs. And you can safely assume other headers should each have their own include guards. – FoggyDay Apr 29 '15 at 20:49
  • 2
    Well, it can't hurt to put the entirety of your header inside the guards. But the other headers that you're including should already be using either "guard" #ifndef's or #pragma once. You can almost always count on system headers following this convention. – Dan Korn Apr 29 '15 at 20:49
  • There is no reason to have includes before include guards. However if '' and '"whatever.h"' have proper guards, there is no concern. –  Apr 29 '15 at 20:52
  • I found an example of this where the outer include contained a define which then excluded the rest of the header file. If I move it inside the include guards, it no longer sees the defines, even though they are included in the previous line. I don't understannnnnd – endolith Apr 17 '21 at 04:03

2 Answers2

9

Potentially, having #include outside the include guards could lead to circular references, etc. If the other files are properly protected, there isn't an issue. If the other files are written like this one, there could be problems.

No, there isn't a good reason that I know of to write the code with the #include lines outside the include guards.

The include guards should be around the whole contents of the header; I can't think of an exception to this (when header guards are appropriate in the first place — the C header <assert.h> is one which does not have header guards for a good reason).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

As long as you don't have circular includes (whatever1.h includes whatever2.h which includes whatever1.h) this should not be a problem, as the code itself is still protected against multiple inclusion.

It will however almost certainly impact compile time (how much depends on the project size) for two reasons:

  1. Modern compilers usually detect "classical" include guards and just ignore any further #includes of that file (just like #pragma once). The structure you are showing prevents that optimization.
  2. Each compilation unit becomes much larger as each file will be included much more often - right before the preprocessor then deletes all the inactive blocks again.

In any case, I can't think of any benefit such a structure would have. Maybe it is the result of some strange historical reasons, like some obscure analysis tool that was used on your codebase in pre-standard C++ time.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
MikeMB
  • 20,029
  • 9
  • 57
  • 102