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.

Smi
  • 13,850
  • 9
  • 56
  • 64
Lonelydove
  • 193
  • 1
  • 5
  • 3
    It's always safe to use it rather than looking for situation where it wouldn't be useful, I think. – Mahesh Jul 22 '11 at 16:37
  • 4
    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). – Kerrek SB Jul 22 '11 at 16:45
  • Show more details on the header file? I'm curious too. – Stan Jul 23 '11 at 09:03
  • 1
    @KerrekSB Please share your tricks! – Santropedro Jul 07 '19 at 05:44
  • 1
    @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](https://en.wikipedia.org/wiki/X_Macro), and the headers "x-headers" (because their filename starts with `x_` or `xx_` in some conventions); see also [here](https://stackoverflow.com/questions/6793161/when-not-to-use-include-guard-in-header-file). Boost.Preprocessor shows how to take this to the extreme. – Kerrek SB Jul 08 '19 at 14:34

4 Answers4

13

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
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
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.

  • So you can't `#include ` in two different files in your projects? – ChronoTrigger Sep 17 '15 at 10:40
  • 3
    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 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. – Yuri Kravchenko Sep 17 '15 at 15:10
  • 1
    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 ``, even if I'm also including my "algorithms.h" file that also includes `` for some reason. Some style guides, as Google's one, suggest you include all the headers of the data types you use. – ChronoTrigger Sep 17 '15 at 15:35
  • And if i want to figure out layer hierarchy thru analysing source code - i can't. And if i want to change 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. – Yuri Kravchenko Sep 17 '15 at 16:23
  • 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 . I think both of our methodologies have pros and cons. – ChronoTrigger Sep 17 '15 at 17:08
  • 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. – underscore_d Oct 28 '16 at 11:29
  • @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. – code_fodder Aug 28 '18 at 11:10
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.

ninjalj
  • 42,493
  • 9
  • 106
  • 148
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.

Oswald
  • 31,254
  • 3
  • 43
  • 68