Include guards do indeed protect your header files from mutual, recursive inclusion. The confusion arises because the issue is not with the guards, but with how data structures are defined in the header files.
Consider the example:
// a.h #ifndef A_H #define A_H #include "b.h" struct A { ... }; #endif // A_H // b.h #ifndef B_H #define B_H #include "a.h" struct B { A* pA; }; #endif // B_H // main.cpp #include "a.h" int main() { ... }
Even with include guards, main.cpp will fail to compile because class A (needed for class B) has an incomplete definition. Forward declarations resolve this issue:
// b.h #ifndef B_H #define B_H // Forward declare A to avoid circular inclusion struct A; struct B { A* pA; }; #endif // B_H
Include guards protect against multiple definitions within a single translation unit, but not across different units. To illustrate:
// header.h #ifndef HEADER_H #define HEADER_H int f() { return 0; } #endif // HEADER_H // source1.cpp #include "header.h" // Redundant include causing multiple definitions #include "header.h" int main() { ... } // source2.cpp #include "header.h" ...
Even with include guards, the linker will complain about multiple definitions of f(). The solution is to define the function in only one translation unit or use the inline keyword to instruct the compiler to inline the function body at each call site.
The above is the detailed content of How Do Include Guards Handle Mutual Recursion and Multiple Symbol Definitions?. For more information, please follow other related articles on the PHP Chinese website!