编译器为何在链接前不对预定义函数报未定义引用错误?
问题:为什么预定义函数未提供定义时编译器不报错?
我们知道预定义函数的定义位于库文件中,链接器的职责是将已编译的库代码与源代码编译后生成的目标文件链接起来。但在链接器工作前,编译器并没有预定义函数的定义,为何它不会报错?
在以下C示例程序中,会报“undefined reference to `f1'”错误,显然是因为找不到函数定义,但为何同样的情况不适用于预定义函数?它们似乎也应该触发报错。
#include<stdio.h> void f1(); int main() { f1(); return 0; }
回答
首先要纠正一个误解:你看到的undefined reference错误不是编译器报的,是链接器报的,两者的职责边界很清晰:
- 编译器只负责把源代码编译成目标文件(.o),它的检查范围仅限于语法是否合法、类型是否匹配,以及你调用的函数有没有对应的声明(函数原型)。只要有了函数声明,编译器就会默认后续链接阶段能找到该函数的实现,不会在编译环节报错。
- 你写的示例里,
void f1();是合法的函数声明,所以编译器顺利通过了编译。但到了链接阶段,链接器既没在你的代码里找到f1的定义,也没在默认链接的系统库中找到,所以才抛出了找不到引用的错误。 - 对于
printf这类预定义函数,<stdio.h>头文件里已经包含了它们的函数声明(比如int printf(const char *format, ...);),编译器看到这个声明就会放行。而链接阶段,编译工具链会自动告诉链接器去链接标准C库(比如libc),这些库中已经包含了预定义函数的实现代码,所以链接器能顺利找到对应的定义,不会报错。
内容的提问来源于stack exchange,提问作者Harsh Chaudhary
相关产品推荐
相关产品推荐

