Include statements outside include guards
Asked Answered
M

2

5

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?

Mendy answered 29/4, 2015 at 20:43 Comment(4)
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.Emergency
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.Egomania
There is no reason to have includes before include guards. However if '<string.h>' and '"whatever.h"' have proper guards, there is no concern.Dearborn
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 understannnnndMaurili
T
4

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.

Tody answered 29/4, 2015 at 21:3 Comment(0)
P
10

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).

Postcard answered 29/4, 2015 at 20:49 Comment(0)
T
4

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.

Tody answered 29/4, 2015 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.