当我在一个头文件中声明一个函数,并将该函数的定义放在其他文件中时,编译器/链接器如何找到该定义?它是否系统地搜索其路径中的每个文件,或者是否有更优雅的解决方案?这在过去几天一直困扰我,我一直无法找到解释。C/C++编译器如何找到头文件中原型的定义?
回答
编译器不会这样做,链接器会这样做。
虽然编译器一次只能处理一个源文件,但在调用链接器时,会传递编译器生成的所有对象文件的名称以及用户希望链接的任何库。因此,链接器对可能包含定义的文件集有完整的了解,只需查看那些目标文件的符号表即可。除此之外,不需要做任何搜索。
例如,假设您有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
第一行编译foo.c,产生foo.o.第二个编译bar.c,生成bar.o.此时,在目标文件bar.o中,foo
是一个外部符号。第三行调用链接器,链接器将foo.o和bar.o链接到一个名为“程序”的可执行文件中。当链接器处理bar.o时,它会看到未解析的外部符号foo
,因此它在链接的所有其他目标文件(在本例中仅为foo.o)的符号表中查找并在foo.o中找到foo
,并且完成链接。
使用库会有点复杂,它们在命令行上出现的顺序可能取决于链接器,但它的原理通常相同。
编译.cpp文件时,编译器输出.obj文件中的两个表:它预期定义的符号列表外部的,以及在该特定的符号列表中模块。
链接程序获取编译器输出的所有.obj文件,然后(顾名思义)链接它们都在一起。因此,对于每个模块,它会查看标记为“外部定义”的符号列表,并查看所有其他模块的符号。
所以它永远只能“搜索”,你告诉它在搜索。
如果无法找到任何其他模块的符号的模块,当你拿到“未定义的引用”错误的。
现在我知道在哪种情况下,我收到“未定义参考”错误。我的意思是说编译器(更确切的说是链接器)找不到预期在其他模块中定义的未解析的外部符号。 – 2016-01-08 09:30:32
假设你有一个带有#include foo.h的foo.cpp,也许还有其他包含。头部当然可以有自己的#include -s。
预处理器将从foo.cpp开始,解析#includes并读取标题内容。结果将是来自头文件和foo.cpp“扁平化”的文本。 然后编译器将处理该文本。如果一个变量/函数/ etc应该有 被声明在某个头文件中没有找到,编译器会报错。
基本的观点是编译器必须查看所有的声明作为.cpp和头文件的结果。
- 1. Qt编译器找不到头文件
- 2. java编译器如何找到没有头文件的类?
- 3. CC编译器中未定义的函数(minix)
- 4. 如何找到MySQL头文件来编译QT
- 5. 编译器在Windows上找不到GCD头文件
- 6. 在一个elf文件中,如何找到变量定义的编译单元?
- 7. 库的头文件中的结构定义和编译差异
- 8. 编译器找不到安装库头
- 9. 为什么编译器找不到.cpp文件中的方法定义
- 10. 如何为自定义编译器编写waf文件?
- 11. 修改makefile编译.CC和.cpp文件
- 12. 编译器找不到ui_xyz.h文件
- 13. 编译器找不到EXE文件
- 14. Typescript编译错误TS2688:找不到'.svn'的类型定义文件
- 15. 编译头文件
- 16. 如何找到包含文件中定义的类型?
- 17. 编译大型头文件C++
- 18. 编译* .cc文件时出现Gcc编译错误
- 19. 如何避免预编译头文件
- 20. 定义头文件中的函数与其他头文件中的原语
- 21. 如何通知TypeScript编译器扩展到JS Array原型?
- 22. 在C程序中包含头文件时,链接器/编译器如何找到相应的代码?
- 23. C++头文件编译器问题(Sales_item.h)C++头文件示例
- 24. 如何在Netbeans上编译预编译头文件?
- 25. 如何在IntelliJ IDEA中为某些文件类型定义自定义编译器?
- 26. 无法定义,利用“动态”编译器所需的类型“System.Runtime.CompilerServices.DynamicAttribute”未找到
- 27. 扩展原型的定义文件
- 28. 为什么编译器无法找到的.cpp模板定义
- 29. C#编译器找不到自定义的DLL参考
- 30. iOS - 编译失败,CocoaPods无法找到头文件
谢谢你提出这个问题。我想知道同样的事情。 – 2014-11-13 15:58:51
发现这真的很有用:http://www.lurklurk.org/linkers/linkers.html – letmaik 2015-02-06 08:45:56