#ifndef Include Guards in C

  1. Use ifndef Include Guard to Protect Against Multiple Inclusion of Header Files in C
  2. Use ifndef Directive to Ensure Macros Aren’t Defined Multiple Times in C

This article will demonstrate multiple methods of how to use #ifndef include guards in C.

Use ifndef Include Guard to Protect Against Multiple Inclusion of Header Files in C

Header files in C are used to define the interface for the functions implemented in the source file with the same name. The interface usually includes function prototypes, definitions for publicly accessible data structures, and some other miscellaneous stuff.

Note that header files may be included in the source file multiple times, leading to compiler errors. Usually, this is prevented with the #ifndef preprocessor directive, which is called wrapper #ifndef. When the contents of the header file are enclosed in the structure shown in the following example, where the directive #ifndef MY_GUARD is the starting point and #endif the ending. ifndef directive checks if the MY_GUARD macro is defined, if not it continues and defines it with the next directive. In case the user includes the same header for the second time, the ifndef directive will evaluate false and ignore the code before the #endif directive. As a result, the compiler will get only one copy of the code from this header file and translate it successfully.

#include <stdio.h>

#ifndef MY_GUARD
#define MY_GUARD 1

#define  PER(D) #D
#define  JOIN(A,B) (A ## B)
#define  JOINX(A,B) JOIN(A,B)

int power(int base, int n) {
    int p = base;
    for (size_t i = 0; i < n; i++) {
      p *= base;
    }
    return p;
}
#endif

Another method to accomplish the same results is to include #pragma once directive in the header file. The preprocessor scans those header files only once and guarantees that they are not read again. One downside of the following method is that it has low portability across the different preprocessors, so one might want to stick with the wrapper #ifndef method to ensure better flexibility of the codebase.

#include <stdio.h>

#pragma once

#define  PER(D) #D
#define  JOIN(A,B) (A ## B)
#define  JOINX(A,B) JOIN(A,B)

int power(int base, int n) {
    int p = base;
    for (size_t i = 0; i < n; i++) {
      p *= base;
    }
    return p;
}

Use ifndef Directive to Ensure Macros Aren’t Defined Multiple Times in C

Alternatively, we can use the ifndef directive to check if the given macro expression has already been defined. The logic works exactly as in the previous example; if the expression is not defined, the next #define directive is processed accordingly. The only line between the #ifndef and #endif is one macro definition, meaning that in case the condition is false, just the given macro is definition is skipped.

#include <stdio.h>
#include <stdlib.h>

#define  PER(D) #D

#ifndef DLEVEL
#define DLEVEL 6
#endif

int main() {

    for (int j = 0; j < DLEVEL; ++j) {
        printf("%s\n", PER(stringify this));
    }

    exit(EXIT_SUCCESS);
}
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.