When not to use include guard in header file?
Asked Answered
H

4

19

We all know when to use include guard, but when shall we not use it in our project?

Recently, I saw a project with mix compilation (CUDA + GCC), one header file (CUDA file) is deliberately left without include guard. I am just curious about it.

Hamann answered 22/7, 2011 at 16:35 Comment(5)
It's always safe to use it rather than looking for situation where it wouldn't be useful, I think.Glad
For normal user library headers, always add include guards. There are some perverse tricks you can pull with repeat inclusion of unguarded headers, but you should never have to do that as a reputable family man (or wife).Homunculus
Show more details on the header file? I'm curious too.Trephine
@KerrekSB Please share your tricks!Cowley
@Santropedro: There are ways to generate code by inclusion of some file that invokes macros, where you really want the file to be included each time. The macros are sometimes called X-macros, and the headers "x-headers" (because their filename starts with x_ or xx_ in some conventions); see also here. Boost.Preprocessor shows how to take this to the extreme.Homunculus
D
14

There are 2 scenarios off the top of my head:

  1. when you want to turn on/off debugging capabilities (as how assert.h works)
  2. for 'x-macro' type of functionality where you have the include file perform 2 parts of problem, such as defining an enum then defining an array of stringified names corresponding to the enums
Dercy answered 22/7, 2011 at 16:39 Comment(0)
H
4

In our projects we never use include guard. We are using include antiguard:

#ifndef _stdafx_h_
#define _stdafx_h_
#else
#error reinclude stdafx.h
#endif

Because if you reincluded same header - you written wrong code or worked with wrong architecture.

Haemolysin answered 17/9, 2015 at 10:30 Comment(7)
So you can't #include <vector> in two different files in your projects?Headlong
Maybe you do not really understand the problem of reincluding headers. Include header in two different .c/.cpp files is not the reinclude. Include header twice in one .cpp file is. If we include <vector> in stdafx.h we don't need include it in over our projects headers. Because headers is not compile, only .cpp. Include guard is some sort of foolproof, for those who don't want to think about the architecture of the application. With include guard we can't see a real hierarchy of layers of the application due to multiple cross-inclusion of the same headers into each other.Haemolysin
I understand projects must be designed in such a way that there are not circular dependencies. Apart from that, I do think including the same header multiple times makes sense logically speaking. For example, if my "application.cpp" defines a vector, I should include <vector>, even if I'm also including my "algorithms.h" file that also includes <vector> for some reason. Some style guides, as Google's one, suggest you include all the headers of the data types you use.Headlong
And if i want to figure out layer hierarchy thru analysing source code - i can't. And if i want to change <vector> to "myvector.h" in project, i must search all source code files, instead of changing only one line in stdafx.h. And if i want to be sure about precompiled header effective using, i can't. I don't like such style guides, sorry.Haemolysin
Analogously, with your style, if "algorithms.h" is changed and now it includes "myvector.h", the application won't compile because "application.cpp" can't find <vector>. I think both of our methodologies have pros and cons.Headlong
Hmm, this is interesting. I might sed this in my own headers in my current project to see whether I'm doing anything redundant or near-circular. In theory, as you said, for non-library/-template headers, reinclusions should not occur.Leix
@YuriKravchenko stdafx.h sounds very microsoft visual studio, what if you are not writing code in MSVS and precompiled headers are irrelevant? - is your "use case" specific to MSVS? I don't really see any issue refactoring. I refactor stuff all the time - change a few header names here and there (compiler will tell you if there is one wrong)...done. What is much more annoying is the header guards, but that is fixed with #pragma once. Also if you want to extract a bit of code, you can see immediately what sort of headers you will need without having to analyse the whole project.Herschel
C
3

One case in when you do want to include the same file several times with different parameters. In this case the include file would act as a sort of template. An example are the scalers on Dosbox.

Concrete answered 22/7, 2011 at 16:44 Comment(0)
P
0

Include guards are used so that the include file can be included multiple times in a single compilation unit without resulting in duplicate declarations.

Do not use include guards when the file should be included multiple times in a single compilation unit and this does not result in duplicate declarations.

Parasympathetic answered 22/7, 2011 at 16:44 Comment(2)
My new generic reply to everything: "Do not use X when X has undesired effects". :pCayser
-1 because this quite literally says "Do not do it when you shouldn't."Maisonette

© 2022 - 2024 — McMap. All rights reserved.