编译中最常见的错误之一发生在链接阶段。该错误看起来与此类似:
$ gcc undefined_reference.c /tmp/ccoXhwF0.o: In function `main': undefined_reference.c:(.text+0x15): undefined reference to `foo' collect2: error: ld returned 1 exit status $
因此,让我们看一下生成此错误的代码:
int foo(void); int main(int argc, char **argv) { int foo_val; foo_val = foo(); return foo_val; }
我们在这里看到了foo()的声明,但没有定义(实际函数)。因此,我们为编译器提供了函数头,但是在任何地方都没有定义此类函数,因此编译阶段通过了,但链接器退出并出现错误。要在我们的小程序中修复此错误,我们只需为foo添加一个定义:int foo();Undefined reference
/* Declaration of foo */ int foo(void); /* Definition of foo */ int foo(void) { return 5; } int main(int argc, char **argv) { int foo_val; foo_val = foo(); return foo_val; }
现在,此代码将编译。另一种情况是,for的源foo()位于单独的源文件中foo.c(并且在和中都包含一个标头foo.h声明)。然后,解决方法是从和链接两个目标文件,或编译两个源文件:foo()foo.cundefined_reference.cfoo.cundefined_reference.c
$ gcc -c undefined_reference.c $ gcc -c foo.c $ gcc -o working_program undefined_reference.o foo.o $
要么:
$ gcc -o working_program undefined_reference.c foo.c $
更复杂的情况是涉及库,如代码中所示:
#include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char **argv) { double first; double second; double power; if (argc != 3) { fprintf(stderr, "Usage: %s <denom> <nom>\n", argv[0]); return EXIT_FAILURE; } /* Translate user input to numbers, extra error checking * should be done here. */ first = strtod(argv[1], NULL); second = strtod(argv[2], NULL); /* Use function pow() from libm - this will cause a linkage * error unless this code is compiled against libm! */ power = pow(first, second); printf("%f to the power of %f = %f\n", first, second, power); return EXIT_SUCCESS; }
该代码在语法上是正确的,声明为pow()from的存在#include <math.h>,因此我们尝试进行编译和链接,但会收到如下错误:
$ gcc no_library_in_link.c -o no_library_in_link /tmp/ccduQQqA.o: In function `main': no_library_in_link.c:(.text+0x8b): undefined reference to `pow' collect2: error: ld returned 1 exit status $
这是因为定义为pow()在链接阶段没有被发现。为了解决这个问题,我们必须指定我们要链接到libm通过指定-lm标志调用的数学库。(请注意,-lm不需要使用诸如macOS之类的平台,但是当您获得未定义的引用时,就需要该库。)
因此,我们再次运行编译阶段,这次指定了库(在源文件或目标文件之后):
$ gcc no_library_in_link.c -lm -o library_in_link_cmd $ ./library_in_link_cmd 2 4 2.000000 to the power of 4.000000 = 16.000000 $
而且有效!