In this article, the reason to use #ifndef and #define header guards in your code is discussed.
Why are #ifndef and #define used in C++ header files
In C++, the #ifdef and #define are used as an instruction for the compiler to protect/guard the multiple usage of header files. For that reason, they are also called header guards. There is a specific syntax which needs to be followed to use #ifndef and #define. So, the syntax is that whenever #ifndef is used, the user is also required to end it by using #endif and between these any declarations or header files can be added:
Syntax
#define FILE_H
//declaration code
#endif
In C++ code, #ifndef and #define identify and prevent the redeclaration of classes, enums, static variables or any other identifiers. This is useful in scenarios where multiple classes/functions are created and are being called in programs. Because many times it happens when a complex code with multiple classes and objects are designed and the developers tend to repeat certain identifiers in different files. For instance, let’s suppose a user has created two correlated files i.e file1.h and a file2.h and has included file1.h in file2.h and vice versa.
By doing this, a repetition occurs causing recursiveness. To avoid this recursiveness if the user adds #ifndef and #define header files, then these headers will instruct the compiler to prevent this recursiveness.
What is Recursiveness in a Code and How “#ifndef” and “#define” Help with Recursiveness
Recursiveness refers to the ability of a function to be included multiple times in a source code. Having recursiveness in a code will generate different types of compilation errors, such as multiple definitions, redefinition of symbols and more. To prevent this recursiveness, we use “#ifndef” and “#define” header guards.
Let’s follow up with an example on how “#ifndef” and “#define” prevents recursiveness in a code. Suppose there is a header file “x.h” that includes the header file “y.h”, and the other head file “y.h” includes “x.h”. This is called recursive inclusion, and it will create errors when you compile the code. To prevent this, we can use #ifndef and #define in x.h and y.h as follows:
The header file x.h is given below:
#define X_H
#include "y.h"
// Remaining Header File content
#endif
The header file y.h is given below:
#define Y_H
#include "x.h"
// Remaining Header File content
#endif
Here, X_H and Y_H are unique symbols defined by #define. The first-time x.h is included, X_H will not be defined, so the preprocessor will define it and include y.h. When y.h is included, Y_H will not be defined, so the preprocessor will define it and include x.h again. However, this time, A_H will be defined, so the preprocessor will skip the inclusion of x.h.
This way the recursive inclusion is prevented and the program can be compiled without errors.
Conclusion
The #ifndef and #define are known as header guards for C++ which are used to prevent/protect the recursiveness or repetition of identifiers. The header guards are used for pre-processing and that is why they are used inside the .h files (header) files and not in the main .cpp (compile-able) file. The syntax and usage of the header guard are discussed in above mentioned guidelines.