#include
in a source file by locating the associated file
on Double inclusion
Example
The following C code demonstrates a real problem that can arise if #include guards are missing:File "grandparent.h"
File "parent.h"
File "child.c"
Result
foo
will thus be defined twice. In C++, this would be called a violation of the one definition rule.
Use of #include guards
Example
In this section, the same code is used with the addition of #include guards. The C preprocessor preprocesses the header files, including and further preprocessing them recursively. This will result in a correct source file, as we will see.File "grandparent.h"
File "parent.h"
File "child.c"
Result
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 for the guardGRANDPARENT_INCLUDED
, CREATORSNAME_YYYYMMDD_HHMMSS
(with the appropriate time information substituted), and names generated from a UUID. (However, _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 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 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
* Circular dependency
* One Definition Rule
* PL/I preprocessor
References
External links