Home > Backend Development > C++ > Why Do Include Guards Fail to Prevent Recursive Inclusion and Multiple Symbol Definitions?

Why Do Include Guards Fail to Prevent Recursive Inclusion and Multiple Symbol Definitions?

DDD
Release: 2024-12-19 15:18:19
Original
488 people have browsed it

Why Do Include Guards Fail to Prevent Recursive Inclusion and Multiple Symbol Definitions?

Why aren't include guards preventing recursive inclusion and multiple symbol definitions?

Recursive Inclusion

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
Copy after login
// source1.cpp
#include "header.h"

A* aPtr = new A;
Copy after login
// source2.cpp
#include "header.h"

B* bPtr = new B;
Copy after login

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
Copy after login

This ensures that the compiler is aware of the existence of class A without providing its definition.

Multiple Symbol Definitions

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
Copy after login
// source1.cpp
#include "header.h"
int main() {
    f();
}
Copy after login
// source2.cpp
#include "header.h"
int main() {
    f();
}
Copy after login

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
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template