我了解在创建 .c 和 .h 文件并将它们添加到我的项目时链接和编译的工作原理。
但是当我向我的项目添加像 stdio.h 这样的头文件时会发生什么?我知道链接器在一些标准目录中搜索 .h 文件,然后将其粘贴进去,但 header 仅包含函数原型(prototype)而没有代码。编译器或链接器在哪里找到这些函数的代码,它是如何添加到我的源文件中的?
我问的原因是因为我正在为微 Controller 编写引导加载程序,我想仔细查看实际发送到编译器的所有 C 代码。我使用的是用于 PIC32 的 XC32 编译器的非优化免费版本,所以我不相信它只包括我实际使用的内容。
最佳答案
您需要区分 header 和库。
header 声明程序可用的设施。当您包含诸如 <stdio.h>
之类的 header 时(注意:这不是 — 重复不是!— 一个库),您就向编译器提供了使用工具所需的信息来自标准 I/O 库。通常,C 头文件不定义实现这些功能的实际代码。 C++ 具有“仅 header ”库(Boost 的某些部分是“仅 header ”库的主要示例)。
库提供设施的实现。 <stdio.h>
header 声明了一个函数 fopen()
;某处有一个库定义了该函数。
一些头文件(实际上,通常是很多头文件)是有特权的,它们声明的功能包含在标准库中,C 编译器将您的程序与之链接。您无需执行任何特殊操作即可将函数链接到您的程序中。其他 header 来自 C 编译器事先不知道的库,对于这些 header ,您必须告诉它在哪里可以找到库(例如,使用 -L /opt/sometool/lib
作为编译器选项)和库名称(例如,使用 -lsometool
,这可能与 /opt/sometool/lib/libsometool.so
或 /opt/sometool/lib/libsometool.a
链接)。请注意,SomeTool 的 header 可能在 /opt/sometool/include
中,您需要添加选项 -I/opt/sometool/include
才能找到 sometool.h
header 。
链接器不引用 header ;编译器本身不引用库。编译器控制程序确实处理混合(它通常将编译过程的多个阶段作为单独的程序运行——编译器与链接器是分开的)。 header 不包含有关库安装位置的信息。
关于c - 当在 C 程序中包含头文件时,链接器/编译器如何找到相应的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35734089/