与gcc和-lm链接并没有在Ubuntu上定义ceil()

时间:2011-11-25 08:03:07

标签: c math.h

我目前正在使用gcc进行编译,我需要使用<math.h>。 问题是它无法识别库。 我也尝试了-lm而没有尝试。 我尝试使用的函数是ceil(),我收到以下错误:

: undefined reference to `ceil'
collect2: ld returned 1 exit status

我正在使用最新的Ubuntu,math.h就在那里。 我尝试在另一台计算机上使用-lm,它可以很好地工作。

有谁知道如何解决这个问题?


我确实包含了<math.h>。另外,我使用的命令是:

gcc -lm -o fb file.c

3 个答案:

答案 0 :(得分:20)

获取此代码并将其放入文件ceil.c

#include <math.h>
#include <stdio.h>
int main(void)
{
    printf("%f\n", ceil(1.2));
    return 0;
}

用以下内容编译:

$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm

其中一个应该有效。如果两者都不起作用,则显示每个编译的完整错误消息。请注意,-lm出现在源文件的名称之后(如果在链接之前将源代码编译为对象,则出现在目标文件中)。

注意:

  1. 现代编译器可能会优化代码,直接将2.0传递给printf(),而无需在运行时调用ceil(),因此根本不需要数学库。

  2. 经验法则在库之前的命令行上列出目标文件和源文件。此答案显示正在使用:-lm位于源文件ceil.c之后。如果您使用make等构建,那么通常在命令行上使用ceil.o(以及其他目标文件);通常,您应该在任何库之前列出所有目标文件。

  3. 经验法则偶尔有例外,但它们很少见,并且会针对预期/需要例外的特定情况进行记录。如果没有相反的明确文件,则应用经验法则。

答案 1 :(得分:9)

没有足够的声誉评论@Jonathan Leffler的回答。只是想提一下Peter van der Linden的书Expert C Programming在第5章Thinking of Linking中对这个问题有一个很好的对待。

  

归档(静态库)的作用与共享对象(动态库)不同。对于动态库,所有库符号都会进入输出文件的虚拟地址空间,并且所有符号都可用于链接中的所有其他文件。相比之下,静态链接仅通过存档查找存档处理时加载程序当前已知的未定义符号。

如果在目标文件之前指定数学库(通常是静态库),则链接器不会添加任何符号。

答案 2 :(得分:3)

尝试编译:

gcc -Wall -g file.c -lm -o file

我遇到了同样的问题,使用此命令解决了问题。此外,如果您在遇到问题的同一天安装了Ubuntu,则可能是更新问题。