【发布时间】:2020-03-06 08:17:53
【问题描述】:
头文件通常使用#ifndef 指令(或类似指令)进行一些安全防护,例如:
//header.hpp
#ifndef HEADER
#define HEADER
//code
#endif
但是,我有一个困惑,如果我们执行以下操作(考虑两个文件的源代码):
//file1.cpp
#include "header.hpp"
//somecode
和文件
//file2.cpp
#include "header.hpp"
//somecode
如果我们这样做:
g++ file1.cpp file2.cpp -o mainfile
我们将获得一个可执行文件,该可执行文件将获得一个没有重复的可执行文件,因为在编译时检查了包含。
但是,如果我们这样做:
g++ -c file1.cpp -o file1.o
g++ -c file2.cpp -o file2.o
g++ 文件1.o 文件2.o -o 主文件.o
在链接阶段会发生什么?包含有冲突吗?在编译期间包含会发生什么?它会重复吗?在这个阶段处理这个问题的底层机制是什么?
【问题讨论】:
-
#include与链接无关。或者编译。它由预处理器完成。 -
在链接阶段没有什么特别的事情发生。如果手动将标头的内容复制到源文件中,结果是一样的。
-
@mathmaniage 再次,指令仅在预处理器阶段处理,这发生在编译器阶段之前,发生在链接器阶段之前。链接器没有指令的概念,它只看到编译器产生的代码,而编译器又只看到预处理器在执行宏替换后产生的代码。给定您的示例,编译器将生成包含相同符号的多个目标文件,然后链接器将丢弃重复项,或者如果它们彼此不兼容,则会出错。
-
@mathmaniage 通常是后者,但现在编译器和链接器做了很多聪明的事情。你真的不需要关心,至少在你的水平上。
-
@mathmaniage "你的水平" = "初学者水平"。