带标题保护的对象文件

时间:2012-02-20 11:01:42

标签: c++ compilation header-files

我对包含标题的目标文件感到有点困惑。如果它们包含在多个目标文件中,我不会看到标题保护如何保护您。

例如:

main.o <- main.cpp class.h
class.o <- class.cpp class.h
main.exe <- main.o class.o

每个目标文件都不会包含class.h,从而使可执行文件有两个副本吗?

3 个答案:

答案 0 :(得分:3)

你是对的,这没问题。标头防护阻止编译器看到两个副本但不影响链接器。实际上,链接器依赖于有两个副本的事实。毕竟,它将这两者联系在一起。

答案 1 :(得分:2)

目标文件不包含标题;它们包含了输出 编译器。但你提出的观点是有效的:标题中的任何内容都可以 在最终代码中重复多次。粗略地说,我们可以 区分两类:

  1. 不会创建可能最终出现的内容的声明 编译器输出:类似于typedef,或者就此而言,模板 和类定义。该标准允许重复定义, 只要他们都“相同”。

  2. 声明您不允许复制,以及哪些声明 不应该在标题中。像变量和函数这样的东西。

  3. 实际上,它有点复杂,可以实例化模板 几个不同来源的同一类型,以及实例化 模板的功能可以是一个功能。或者编译器可能无法内联 内联函数。解决这个问题的常用方法是编译器 在每个转换单元中生成函数,并为链接器生成函数 抛弃重复。 (事实上​​,大多数链接器不检查是否 他们真的是重复的。除了一个,他们只是扔掉了所有人 或多或少随意。)

答案 2 :(得分:0)

标头防护会阻止编译器处理头文件两次(这可能会产生无用的错误,因为一旦定义了类,就不允许重新定义类)。

如果头文件包含编译器实际需要为其生成代码(或数据)的内容,那么 将出现在每个目标文件中。

接下来是链接器处理它,这可能导致链接器错误(例如,如果您包含函数的代码而不说它是内联的,导致2个相同函数的实例),或者没有问题(当你声明函数是内联的时候,在这种情况下链接器只会选择一个)。

大多数情况下,标头只包含函数原型(不生成代码),类定义(不生成代码)内联函数定义或外部引用。其中最后两个将在目标文件中生成需要由链接器处理的内容。