Header Guard
   HOME

TheInfoList



OR:

In the C and
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
programming languages, an #include guard, sometimes called a macro guard, header guard or file guard, is a particular construct used to avoid the problem of ''double inclusion'' when dealing with the
include directive Many programming languages and other computer files have a directive, often called include (sometimes copy or import), that causes the contents of the specified file to be inserted into the original file. These included files are called copybooks ...
. The
C preprocessor The C preprocessor is the macro preprocessor for the C, Objective-C and C++ computer programming languages. The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control ...
processes directives of the form #include in a
source file In computing, source code, or simply code, is any collection of code, with or without comments, written using a human-readable programming language, usually as plain text. The source code of a program is specially designed to facilitate the wo ...
by locating the associated file on
disk Disk or disc may refer to: * Disk (mathematics), a geometric shape * Disk storage Music * Disc (band), an American experimental music band * ''Disk'' (album), a 1995 EP by Moby Other uses * Disk (functional analysis), a subset of a vector sp ...
and transcluding ("including") its contents into a copy of the source file known as the translation unit, replacing the include directive in the process. The files included in this regard are generally
header files Many programming languages and other computer files have a directive, often called include (sometimes copy or import), that causes the contents of the specified file to be inserted into the original file. These included files are called copybooks ...
, which typically contain declarations of functions and classes or structs. If certain C or C++ language constructs are defined twice, the resulting translation unit is invalid. #include guards prevent this erroneous construct from arising by the double inclusion mechanism. The addition of #include guards to a header file is one way to make that file
idempotent Idempotence (, ) is the property of certain operation (mathematics), operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application. The concept of idempotence ...
. Another construct to combat ''double inclusion'' is #pragma once, which is non-standard but nearly universally supported among C and C++
compilers In computing, a compiler is a computer program that translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primarily used for programs that ...
.


Double inclusion


Example

The following C code demonstrates a real problem that can arise if #include guards are missing:


File "grandparent.h"

struct foo ;


File "parent.h"

#include "grandparent.h"


File "child.c"

#include "grandparent.h" #include "parent.h"


Result

struct foo ; struct foo ; Here, the file "child.c" has indirectly included two copies of the text in the
header file Many programming languages and other computer files have a directive, often called include (sometimes copy or import), that causes the contents of the specified file to be inserted into the original file. These included files are called copybooks ...
"grandparent.h". This causes a
compilation error Compilation error refers to a state when a compiler fails to compile a piece of computer program source code, either due to errors in the code, or, more unusually, due to errors in the compiler itself. A compilation error message often helps program ...
, since the structure type foo will thus be defined twice. In C++, this would be called a violation of the
one definition rule The One Definition Rule (ODR) is an important rule of the C++ programming language that prescribes that classes/structs and non-inline functions cannot have more than one definition in the entire program and template and types cannot have more than ...
.


Use of #include guards


Example

In this section, the same code is used with the addition of #include guards. The
C preprocessor The C preprocessor is the macro preprocessor for the C, Objective-C and C++ computer programming languages. The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control ...
preprocesses the header files, including and further preprocessing them
recursively Recursion (adjective: ''recursive'') occurs when a thing is defined in terms of itself or of its type. Recursion is used in a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in mathematics ...
. This will result in a correct source file, as we will see.


File "grandparent.h"

#ifndef GRANDPARENT_H #define GRANDPARENT_H struct foo ; #endif /* GRANDPARENT_H */


File "parent.h"

#include "grandparent.h"


File "child.c"

#include "grandparent.h" #include "parent.h"


Result

struct foo ; Here, the first inclusion of "grandparent.h" has the macro GRANDPARENT_H defined. When "child.c" includes "grandparent.h" at the second time, as the #ifndef test returns false, the preprocessor skips down to the #endif, thus avoiding the second definition of struct foo. The program compiles correctly.


Discussion

Different
naming conventions A naming convention is a convention (generally agreed scheme) for naming things. Conventions differ in their intents, which may include to: * Allow useful information to be deduced from the names based on regularities. For instance, in Manhatta ...
for the guard macro may be used by different
programmer A computer programmer, sometimes referred to as a software developer, a software engineer, a programmer or a coder, is a person who creates computer programs — often for larger computer software. A programmer is someone who writes/creates ...
s. Other common forms of the above example include GRANDPARENT_INCLUDED, CREATORSNAME_YYYYMMDD_HHMMSS (with the appropriate time information substituted), and names generated from a
UUID A universally unique identifier (UUID) is a 128-bit label used for information in computer systems. The term globally unique identifier (GUID) is also used. When generated according to the standard methods, UUIDs are, for practical purposes, uni ...
. (However,
name A name is a term used for identification by an external observer. They can identify a class or category of things, or a single thing, either uniquely, or within a given context. The entity identified by a name is called its referent. A personal ...
s starting with one underscore and a
capital letter Letter case is the distinction between the letters that are in larger uppercase or capitals (or more formally ''majuscule'') and smaller lowercase (or more formally ''minuscule'') in the written representation of certain languages. The writing ...
or any name containing double underscore, such as _GRANDPARENT__H and __GRANDPARENT_H, are reserved to the language implementation and should not be used by the user.) Of course, it is important to avoid duplicating the same include-guard macro name in different header files, as including the 1st will prevent the 2nd from being included, leading to the loss of any declarations, inline definitions, or other #includes in the 2nd header.


Difficulties

For #include guards to work properly, each guard must test and conditionally set a different preprocessor macro. Therefore, a project using #include guards must work out a coherent naming scheme for its include guards, and make sure its scheme doesn't conflict with that of any third-party headers it uses, or with the names of any globally visible macros. For this reason, most C and C++ implementations provide a non-standard #pragma once directive. This directive, inserted at the top of a header file, will ensure that the file is included only once. The
Objective-C Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTS ...
language (which is a superset of C) introduced an #import directive, which works exactly like #include, except that it includes each file only once, thus obviating the need for #include guards.


Other languages

PL/I PL/I (Programming Language One, pronounced and sometimes written PL/1) is a procedural, imperative computer programming language developed and published by IBM. It is designed for scientific, engineering, business and system programming. I ...
uses the %INCLUDE statement as the equivalent to C's #include directive. IBM Enterprise PL/I also supports the %XINCLUDE statement which will "incorporate external text into the source program if it has not previously been included." This differs from the C #pragma once in that the program including the external text is responsible for specifying that duplicate text should not be included, rather than the included text itself. It also offers an XPROCEDURE statement, similar to a PROCEDURE statement, which will ignore the second and subsequent occurrences of an XPROCEDURE with the same name,{{cite book , last1=IBM Corporation , title=Enterprise PL/I for z/OS PL/I for AIX Enterprise PL/I for z/OS Language Reference Version 5 Release 1 , date=August 2017 , page=257 , url=https://www.ibm.com/docs/en/SSY2V3_5.1.0/com.ibm.ent.pl1.zos.doc/lrm.pdf , access-date=Apr 7, 2022


See also

* #pragma once *
C preprocessor The C preprocessor is the macro preprocessor for the C, Objective-C and C++ computer programming languages. The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control ...
*
Circular dependency In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive. Overview Circular depend ...
*
One Definition Rule The One Definition Rule (ODR) is an important rule of the C++ programming language that prescribes that classes/structs and non-inline functions cannot have more than one definition in the entire program and template and types cannot have more than ...
* PL/I preprocessor


References


External links


Include guard optimisationRedundant Include Guards
C (programming language) headers