20

我目前正在使用 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
4

3 回答 3

30

获取此代码并将其放入文件中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。如果您正在使用makeetc 构建,那么您通常ceil.o在命令行上使用(以及其他目标文件);通常,您应该在任何库之前列出所有目标文件。

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

于 2011-11-25T08:16:36.643 回答
10

只是想提一下,Peter van der Linden 的书Expert C Programming在第 5 章Thinking of Linking中对此主题进行了很好的处理。

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

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

于 2011-11-25T08:41:36.113 回答
7

尝试这样编译:

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

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

于 2014-12-17T18:45:35.447 回答