Use of #include guards
File “Grandparent.h”
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct Foo {
int member;
};
#endif /* GRANDPARENT_H */
File “Parent.h”
#include "Grandparent.h"
File “Child.c”
#include "Grandparent.h"
#include "Parent.h"
Intermediate step
// Contents from "Grandparent.h"
#ifndef GRANDPARENT_H // GRANDPARENT_H is not defined
#define GRANDPARENT_H
struct Foo { // This definition is compiled
int member;
};
#endif /* GRANDPARENT_H */
// Contents from "Parent.h"
#ifndef GRANDPARENT_H // GRANDPARENT_H is already defined
#define GRANDPARENT_H
struct Foo { // This definition is not compiled
int member;
};
#endif /* GRANDPARENT_H */
Result
struct Foo {
int member;
};
Here, the first inclusion of “Grandparent.h” has the macro GRANDPARENT_H defined. When “Child.c” includes “Grandparent.h” at the second time (while including “Parent.h”), 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.