首页 >后端开发 >C++ >为什么我的包含防护无法防止递归包含和多个符号定义?

为什么我的包含防护无法防止递归包含和多个符号定义?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-22 19:37:11553浏览

Why Are My Include Guards Failing to Prevent Recursive Inclusion and Multiple Symbol Definitions?

为什么我的包含防护不能防止递归包含和多个符号定义?

第一个问题:

为什么不包含保护我的头文件免受相互递归的影响包容?

包容警卫正在做他们的工作。该问题是由相互包含的标头中数据结构定义之间的依赖关系引起的。

例如,假设 a.h 和 b.h 包含:

// a.h
#ifndef A_H
#define A_H
#include "b.h"
struct A {...};
#endif

// b.h
#ifndef B_H
#define B_H
#include "a.h"
struct B {...};
#endif

如果没有包含防护,main.cpp 将不会由于编译深度限制而进行编译。

使用包含防护,可以防止无限递归。然而,定义之间的依赖关系仍然存在:

  • 编译 a.h 时,预处理器遇到 #include "b.h" 并对其进行处理。
  • 处理 b.h 时,它遇到 #include "a.h" 并处理它。再次处理它。
  • 这会创建一个依赖关系,其中必须先定义 A,然后才能定义 B

要解决此问题,请在需要它们的标头中使用前向声明:

// b.h
#ifndef B_H
#define B_H
struct A; // Forward declaration
struct B {...};
#endif

第二个问题:

为什么不包含防止多重定义的守卫?

包含守卫可以防止重新定义在单个翻译单元内,但不能跨不同单元。

例如,当 header.h:

#ifndef HEADER_H
#define HEADER_H
int f() {...};
#endif

包含在多个翻译单元中时,例如 source1.cpp 和 source2.cpp :

// source1.cpp
#include "header.h"

// source2.cpp
#include "header.h"

链接器会抱怨 f() 的多个定义,因为它在单独的对象中看到相同的定义

要解决此问题,请使用以下方法:

  • 内联关键字:指示编译器内联函数体,允许在没有链接器的情况下进行多个定义错误。
  • 静态关键字:提供函数内部链接,为每个函数创建一个私有副本翻译单元。
  • 未命名命名空间:在未命名命名空间中声明函数会为其提供内部链接,从而防止多重定义。

以上是为什么我的包含防护无法防止递归包含和多个符号定义?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn