Include guards provide protection against recursive inclusion, but they can't prevent dependencies between data structure definitions in mutually-including headers. Consider the following code:
// header.h #ifndef HEADER_H #define HEADER_H class A; class B { public: A* pA; }; #endif // HEADER_H
// source1.cpp #include "header.h" A* aPtr = new A;
// source2.cpp #include "header.h" B* bPtr = new B;
In this scenario, source1.cpp includes header.h, which includes source2.cpp (indirectly). This behavior is prevented by include guards, but the compiler will still report an error because class A is not defined in header.h.
To solve this issue, forward declarations can be used in header.h:
// header.h #ifndef HEADER_H #define HEADER_H struct A; class B { public: A* pA; }; #endif // HEADER_H
This ensures that the compiler is aware of the existence of class A without providing its definition.
Include guards prevent multiple symbol definitions within the same translation unit (.cpp file). However, they don't protect against multiple definitions across separate translation units.
Consider the following code:
// header.h #ifndef HEADER_H #define HEADER_H int f() { return 0; } #endif // HEADER_H
// source1.cpp #include "header.h" int main() { f(); }
// source2.cpp #include "header.h" int main() { f(); }
In this example, the function f() is defined in header.h. When source1.cpp and source2.cpp are compiled separately, the include guards will prevent multiple definitions within each translation unit. However, when the object code is linked together, the linker will detect multiple definitions of f().
To solve this issue, the inline keyword can be used to tell the compiler to inline the function definition directly at the call site:
// header.h #ifndef HEADER_H #define HEADER_H inline int f() { return 0; } #endif // HEADER_H
Alternatively, the function definition can be moved to a separate .cpp file to avoid conflicting with the definitions in other translation units.
The above is the detailed content of Why Do Include Guards Fail to Prevent Recursive Inclusion and Multiple Symbol Definitions?. For more information, please follow other related articles on the PHP Chinese website!