使用头文件时未定义的符号错误

时间:2010-06-04 07:00:36

标签: c linker-errors undefined-reference undefined-symbol

我收到了以下错误,并且在我的生活中无法弄清楚我做错了什么。

$ gcc main.c -o main

Undefined symbols:
  "_wtf", referenced from:
      _main in ccu2Qr2V.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

main.c中:

#include <stdio.h>
#include "wtf.h"

main(){
    wtf();
}

wtf.h:

void wtf();

wtf.c:

void wtf(){
    printf("I never see the light of day.");
}

现在,如果我将整个函数包含在头文件中而不仅仅是签名中,那么它就符合要求,所以我知道包含wtf.h。为什么编译器看不到wtf.c?或者我错过了什么?

问候。

2 个答案:

答案 0 :(得分:11)

您需要将wtfmain相关联。最简单的编译方式 - gcc将为您链接'em,就像这样:

gcc main.c wtf.c -o main

更长的方式(单独编译wtf):

gcc -c wtf.c
gcc main.c wtf.o -o main

更长(单独的编译和链接)

gcc -c wtf.c
gcc -c main.c
gcc main.o wtf.o -o main

您可以直接运行gcc而不是上一次ld来电,效果相同。

答案 1 :(得分:4)

您遗漏的事实是,仅包含标题并不会告诉编译器任何关于标题中声明的实际实现(定义)的位置。

它们可以位于执行包含的文件旁边的C文件中,它们可以来自预编译的静态链接库,也可以来自系统链接器在读取可执行文件时加载的动态库,或者它们可以在运行时运行-time用户程序员控制的显式动态加载(例如Linux中的dlopen()函数系列)。

C不像Java,没有隐含的规则只是因为一个C文件包含某个头,编译器也应该做一些事情来“神奇地”找到头部声明的事情的实现。你需要告诉它。