Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The use of double include guards in C++

Tags:

c++

macros

linker

So I recently had a discussion where I work, in which I was questioning the use of a double include guard over a single guard. What I mean by double guard is as follows:

Header file, "header_a.hpp":

#ifndef __HEADER_A_HPP__ #define __HEADER_A_HPP__ ... ... #endif 

When including the header file anywhere, either in a header or source file:

#ifndef __HEADER_A_HPP__ #include "header_a.hpp" #endif 

Now I understand that the use of the guard in header files is to prevent multiple inclusion of an already defined header file, it's common and well documented. If the macro is already defined, the entire header file is seen as 'blank' by the compiler and the double inclusion is prevented. Simple enough.

The issue I don't understand is using #ifndef __HEADER_A_HPP__ and #endif around the #include "header_a.hpp". I'm told by the coworker that this adds a second layer of protection to inclusions but I fail to see how that second layer is even useful if the first layer absolutely does the job (or does it?).

The only benefit I can come up with is that it outright stops the linker from bothering to find the file. Is this meant to improve compilation time (which was not mentioned as a benefit), or is there something else at work here that I am not seeing?

like image 378
sh3rifme Avatar asked Jun 19 '17 11:06

sh3rifme


People also ask

Why do we need include guards?

Solution: Include guards ensures that compiler will process this file only once, no matter how many times it is included. Include guards are just series of preprocessor directives that guarantees file will only be included once.

Why do we need header guards in C?

Header Guard in C++ Header Guards in C++ are conditional compilation directives that help to avoid errors that arise when the same function or variable is defined more than once by the mistake of a programmer. According to C++, when a function or a variable is defined more than once, it yields an error.

Why should we use include guards in our header files?

Header guards are designed to ensure that the contents of a given header file are not copied, more than once, into any single file to prevent duplicate definitions.

What does #ifndef Mean?

The #ifndef directive checks whether a macro is not defined. If the identifier specified is not defined as a macro, the lines of code immediately follow the condition are passed on to the compiler.


1 Answers

I am pretty sure that it is a bad practice to add another include guard like:

#ifndef __HEADER_A_HPP__ #include "header_a.hpp" #endif 

Here are some reasons why:

  1. To avoid double inclusion it is enough to add a usual include guard inside the header file itself. It does the job well. Another include guard in the place of inclusion just messes the code and reduces readability.

  2. It adds unnecessary dependencies. If you change include guard inside the header file you have to change it in all places where the header is included.

  3. It is definitely not the most expensive operation comparing the whole compilation/linkage process so it can hardly reduce the total build time.

  4. Any compiler worth anything already optimizes file-wide include-guards.

like image 158
Edgar Rokjān Avatar answered Sep 18 '22 23:09

Edgar Rokjān