未定义的引用`pow'和`floor'

时间:2011-12-29 17:50:49

标签: c gcc undefined-reference

我正在尝试在C中制作一个简单的斐波纳契计算器,但在编译时gcc告诉我,我错过了战俘和地板功能。怎么了?

代码:

#include <stdio.h>
#include <math.h>

int fibo(int n);

int main() {
        printf("Fib(4) = %d", fibo(4));
        return 0;
}

int fibo(int n) {
        double phi = 1.61803399;

        return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

输出:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status

6 个答案:

答案 0 :(得分:220)

您需要使用链接标志-lm进行编译,如下所示:

gcc fib.c -lm -o fibo

这将告诉gcc将您的代码与数学库链接起来。请务必将标记>放在要链接的对象之后。

答案 1 :(得分:24)

将-lm添加到链接选项中,因为pow()和floor()是数学库的一部分:

gcc fib.c -o fibo -lm

答案 2 :(得分:9)

为了以后读到这篇文章的人的利益,你需要像弗雷德所说的那样联系它:

gcc fib.c -lm -o fibo

找出需要链接的库的一个好方法是检查手册页是否存在。例如,man powman floor都会告诉您:

-lm链接。

在C编程中链接数学库的解释 - Linking in C

答案 3 :(得分:8)

关于Fuzzy提供的答案:

我实际上必须做一些稍微不同的事情。

项目 - &gt;属性 - &gt; C / C ++ Build - &gt;设置 - &gt; GCC C Linker - &gt;库

点击小绿色添加图标,输入m并点击确定。此窗口中的所有内容都会自动应用-l,因为它是一个库。

答案 4 :(得分:6)

要找到在Eclipse-IDE中添加-lm的地方非常可怕,所以我花了一些时间。

如果其他人也使用Edlipse,以下是添加命令的方法:

项目 - &gt;属性 - &gt; C / C ++ Build - &gt;设置 - &gt; GCC C Linker - &gt; Miscelleaneous - &gt;链接器标志:在此字段中添加命令-lm

答案 5 :(得分:0)

以上所有答案都不完整,这里的问题出在链接器ld而不是编译器collect2: ld returned 1 exit status上。在编译fib.c反对时:

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
                 U floor
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pow
                 U printf

nm列出了目标文件中的符号。您可以看到它已正确编译,但是powfloorprintf函数具有未定义的引用,现在,如果我尝试将其链接到可执行文件:

$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

我得到的输出类似。为了解决这个问题,我需要告诉链接器在哪里寻找对powfloor的引用,为此,我将链接器-l标志与m一起使用libm.so库。

$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t 
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
                 U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
                 U pow@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__

您现在可以看到,功能powfloor已链接到GLIBC_2.2.5

参数顺序也很重要,除非您的系统默认配置为使用共享库,否则我的系统不是,所以当我发出以下命令时:

$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

在目标文件之前注意-lm标志。因此,总而言之,请确保在所有其他标志和参数之后添加-lm标志。