Joe*_*oel 21 c c++ header forward-declaration
当我在头文件中声明一个函数,并将该函数的定义放在其他文件中时,编译器/链接器如何找到定义?它是否系统地搜索其路径中的每个文件,还是有更优雅的解决方案?这一天一直困扰着我,我一直无法找到解释.
Tyl*_*nry 25
编译器不会这样做,链接器会这样做.
虽然编译器一次只能处理一个源文件,但是当调用链接器时,它会传递编译器生成的所有目标文件的名称,以及用户希望链接的任何库.因此,链接器完全了解可能包含该定义的文件集,并且只需要查看这些目标文件的符号表.除此之外,它不需要进行任何搜索.
例如,假设您有foo.h和foo.c定义和实现函数foo(),以及bar.h和bar.c定义和实现bar().说bar调用,foo使bar.c包含foo.h. 这个编译有三个步骤:
gcc -c foo.c
gcc -c bar.c
gcc foo.o bar.o -o program
Run Code Online (Sandbox Code Playgroud)
第一行编译foo.c,生成foo.o. 第二个编译bar.c,生成bar.o. 此时,在目标文件bar.o中,foo是一个外部符号.第三行调用链接器,它将foo.o和bar.o链接到一个名为"program"的可执行文件中.当链接器处理bar.o时,它会看到未解析的外部符号foo,因此它在链接的所有其他目标文件的符号表中查找(在本例中只是foo.o)并foo在foo.o中查找,并完成链接.
使用库时,这有点复杂,它们在命令行中出现的顺序可能会取决于您的链接器,但它通常是相同的原则.
Dea*_*ing 14
编译.cpp文件时,编译器会在.obj文件中输出两个表:它希望在外部定义的符号列表,以及在该特定模块中定义的符号列表.
链接器获取编译器输出的所有.obj文件,然后(顾名思义)将它们全部链接在一起.因此,对于每个模块,它查看标记为"外部定义"的符号列表,并查看为这些符号指定的所有其他模块.
所以它只会"搜索"你告诉它搜索的模块.
如果它在任何其他模块中找不到符号,那么当您收到"未定义的引用"错误时.