对“pow”和“floor”的未定义引用

Undefined reference to `pow' and `floor'

提问人:kettlepot 提问时间:12/30/2011 最后编辑:Yann Droneaudkettlepot 更新时间:9/13/2019 访问量:240809

问:

我正在尝试用 C 语言制作一个简单的斐波那契计算器,但在编译时告诉我我缺少 pow 和 floor 函数。怎么了?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
c gcc 未定义引用

评论

0赞 vonbrand 1/20/2013
由于浮点精度不是无限的,因此对于不太大的值,这将给出错误的答案n
0赞 Toby Speight 5/2/2018
对 sqrt(或其他数学函数)的未定义引用的可能重复
0赞 OrenIshShalom 7/29/2018
似乎存在一个更简单的解决方案,只需改用 g++:g++ fib.c -o fibo

答:

274赞 Fred 12/30/2011 #1

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

gcc fib.c -lm -o fibo

这将告诉 gcc 将您的代码链接到数学库。只要确保将标志放在要链接的对象之后即可。

评论

9赞 kettlepot 12/30/2011
你能解释一下如何计算出要放在 -l 之后的字母吗?
52赞 ams 12/30/2011
查看 /lib 或 /usr/lib。这些库都是命名的,或者 - ><它是你放在 .在这种情况下,数学库被命名为 ,所以我们称之为 。lib<name>.alib<name>.so-llibm.so-lm
4赞 Dave Baghdanov 11/7/2013
谢谢!在过去的 30 分钟里,我一直在谷歌上搜索,这是第一个说在对象之后链接库的参考
1赞 lindes 2/8/2022
作为对@GabrieleCirulli的评论的回应(很久以前的评论;对不起,现在@你!),我想补充一点,找出这个问题的另一种方法是查看相关函数的手册页,特别是手册第 3 节中的手册页——即类型和/或,它们都应该提到链接器标志。man 3 floorman 3 pow-lm
1赞 lindes 2/8/2022
@KenIngram:这看起来像是标题的C++版本......对 C++ 有效,但非 C++ C 编译器可能会窒息(对我来说确实如此,尽管它很好。gccg++
26赞 Yann Droneaud 12/30/2011 #2

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

gcc fib.c -o fibo -lm
7赞 Fuzzy 10/16/2013 #3

在Eclipse-IDE中找到添加-lm的位置真的很可怕,所以我花了一些时间。

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

项目 -> 属性 -> C/C++ 生成 -> 设置 -> GCC C 链接器 -> 杂项 -> 链接器标志:在此字段中添加命令 -lm

9赞 Greg K 6/23/2014 #4

关于Fuzzy提供的答案:

实际上,我不得不做一些稍微不同的事情。

项目 -> 属性 -> C/C++ 生成 ->设置 -> GCC C 链接器 -> 库

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

10赞 spike.barnett 5/15/2015 #5

为了以后阅读本文的任何人的利益,您需要像 Fred 所说的那样链接到它:

gcc fib.c -lm -o fibo

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

与 链接。-lm

在 C 编程中链接数学库的解释 - 在 C 语言中链接

4赞 bladekp 9/13/2019 #6

上面的所有答案都是不完整的,这里的问题在于链接器而不是编译器。编译 to object 时:ldcollect2: ld returned 1 exit statusfib.c

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

其中列出了目标文件中的符号。您可以看到它被编译时没有错误,但是 、 和函数具有未定义的引用,现在如果我尝试将其链接到可执行文件:nmpowfloorprintf

$ 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-lmlibm.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__

您现在可以看到,函数 链接到 。powfloorGLIBC_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