未定义的引用`sin`

rob*_*ntw 90 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;
}
Run Code Online (Sandbox Code Playgroud)

gcc test.c我编译它时,我得到以下错误,我无法解决原因:

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

但是,我编写了各种sinmain函数内部调用的测试程序,并且这些程序完美地工作.我必须在这里做一些明显错误的事 - 但它是什么?

Edw*_*uck 110

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

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

评论中,linuxD问:

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

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

该标准专门从"标准C数学库"例程(第277页)中分离出"标准C库"例程.相关段落复制如下:

标准C库

自动搜索标准C库 cc以解析外部引用.除了Math Routines之外,该库支持第1卷中定义的Base System的所有接口.

标准C数学图书馆

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

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

  1. UNIX战争导致从原来的AT&T UNIX发行增加发散.
  2. UNIX平台的数量增加了为操作系统开发软件的难度.
  3. 试图为软件开发人员定义最低公分母,称为1988 POSIX.
  4. 软件开发人员针对POSIX标准进行编程,以便在"POSIX兼容系统"上提供其软件,以便覆盖更多平台.
  5. UNIX客户要求"POSIX兼容"UNIX系统来运行该软件.

决定投入-lm不同图书馆的压力可能包括但不限于:

  1. 这似乎是保持libc大小的好方法,因为许多应用程序不使用嵌入在数学库中的函数.
  2. 它为数学库实现提供了灵活性,其中一些数学库依赖于较大的嵌入式查找表,而其他数学库可能依赖于较小的查找表(计算解决方案).
  3. 对于真正受大小限制的应用程序,它允许以非标准方式重新实现数学库(例如拔出sin()并将其放入自定义构建的库中).

在任何情况下,它现在都是标准的一部分,不能自动包含在C语言中,这就是你必须添加的原因-lm.

  • 为什么对于sin(math.h),我们需要-lm选项显式而不是stdio.h中定义的printf()fn,我怀疑GNU的链接器功能.就像在VCC中一样,它也可以在mac上工作,就像flarn2006所提到的那样. (3认同)
  • @KeithThompson 在答案中添加了很多内容以取消评论。享受。 (2认同)

小智 62

无论如何我添加了-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
Run Code Online (Sandbox Code Playgroud)

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

gcc mtest.c -o mtest.o -lm
Run Code Online (Sandbox Code Playgroud)

只是链接没有问题

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


Pau*_*l R 38

你需要链接数学库libm:

$ gcc -Wall foo.c -o foo -lm 
Run Code Online (Sandbox Code Playgroud)


bla*_*ppy 10

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