未定义的引用`sin`

时间:2011-02-15 15:09:27

标签: c math linker-errors undefined-reference

我有以下代码(针对此问题简化了基础知识):

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

double f1(double x)
{
    double res = sin(x);
    return 0;
}

/* The main function */
int main(void)
{
    return 0;
}

使用gcc test.c进行编译时出现以下错误,我无法理解原因:

/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status

但是,我编写了各种测试程序,从sin函数中调用main,这些程序完美无缺。我必须在这里做一些明显错误的事 - 但它是什么?

4 个答案:

答案 0 :(得分:109)

您已编译代码并引用了正确的math.h头文件,但是当您尝试链接它时,您忘记了包含数学库的选项。因此,您可以编译.o目标文件,但不能构建可执行文件。

正如Paul已经提到的,在您尝试生成可执行文件的步骤中添加“-lm”以链接数学库。

commentlinuxD问:

  

为什么sin()中的<math.h>,我们是否明确需要-lm选项;但,   不是printf()中的<stdio.h>

因为这两个函数都是作为“Single UNIX Specification”的一部分实现的。该标准的历史很有意思,并且有许多名称(IEEE Std 1003.1,X / Open Portability Guide,POSIX,Spec 1170)。

此标准specifically separates out the "Standard C library" routines from the "Standard C Mathematical Library" routines (page 277)。相关段落复制如下:

  

标准C库

     

自动搜索标准C库   cc解析外部参考。这个库支持所有的   基本系统的接口,如第1卷中所定义,除了   数学例程。

     

标准C数学图书馆

     

此库支持   基本系统数学例程,如第1卷中所定义。cc选项   -lm用于搜索此库。

这种分离背后的原因受到许多因素的影响:

  1. UNIX wars导致与最初的AT&amp; T UNIX产品的差异越来越大。
  2. UNIX平台的数量增加了为操作系统开发软件的难度。
  3. 尝试为软件开发人员定义最低标准,called 1988 POSIX
  4. 软件开发人员针对POSIX标准编程,在“符合POSIX标准的系统”上提供软件,以便覆盖更多平台。
  5. UNIX客户要求使用“POSIX兼容”UNIX系统来运行该软件。
  6. -lm放入不同图书馆的决定所带来的压力可能包括但不限于:

    1. 这似乎是一种保持libc大小的好方法,因为许多应用程序不使用嵌入在数学库中的函数。
    2. 它提供了数学库实现的灵活性,其中一些数学库依赖于更大的嵌入式查找表,而其他数学库可能依赖于较小的查找表(计算解决方案)。
    3. 对于真正受大小限制的应用程序,它允许以非标准方式重新实现数学库(例如仅提取sin()并将其放入自定义构建的库中。
    4. 在任何情况下,它现在都是标准的一部分,不会自动包含在C语言中,这就是你必须添加-lm的原因。

答案 1 :(得分:61)

无论如何我添加了-lm

gcc -Wall -lm mtest.c -o mtest.o
mtest.c: In function 'f1':
mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable]
/tmp/cc925Nmf.o: In function `f1':
mtest.c:(.text+0x19): undefined reference to `sin'
collect2: ld returned 1 exit status

我最近发现如果你第一次指定-lm它就不起作用。订单很重要:

gcc mtest.c -o mtest.o -lm

只是链接没有问题

所以你必须在之后指定库。

答案 2 :(得分:38)

您需要链接数学库libm:

$ gcc -Wall foo.c -o foo -lm 

答案 3 :(得分:10)

我有同样的问题,在我最后列出我的库之后就消失了:gcc prog.c -lm