对“sin”的未定义引用

发布于 2024-10-18 01:28:30 字数 542 浏览 6 评论 0原文

我有以下代码(针对这个问题精简到最基本的内容):

#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

但是,我我已经编写了各种从 main 函数中调用 sin 的测试程序,并且这些程序运行得很好。我一定在这里做了一些明显错误的事情 - 但它是什么?

I have the following code (stripped down to the bare basics for this question):

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

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

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

When compiling it with gcc test.c I get the following error, and I can't work out why:

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

However, I've written various test programs that call sin from within the main function, and those work perfectly. I must be doing something obviously wrong here - but what is it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心的憧憬 2024-10-25 01:28:31

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

I had the same problem, which went away after I listed my library last: gcc prog.c -lm

弃爱 2024-10-25 01:28:30

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

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

评论中,linuxD 询问:

为什么对于中的sin(),我们需要显式地使用-lm选项;但,
不适用于 中的 printf()

因为这两个功能都是作为“单一 UNIX 规范”的一部分实现的。该标准的历史很有趣,并且有许多名称(IEEE Std 1003.1、X/Open 可移植性指南、POSIX、Spec 1170)。

该标准专门将“标准 C 库”例程与“标准 C 数学库”分开例程(第 277 页)。相关段落抄录如下:

标准 C 库

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

标准 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 的原因。

You have compiled your code with references to the correct math.h header file, but when you attempted to link it, you forgot the option to include the math library. As a result, you can compile your .o object files, but not build your executable.

As Paul has already mentioned add "-lm" to link with the math library in the step where you are attempting to generate your executable.

In the comment, linuxD asks:

Why for sin() in <math.h>, do we need -lm option explicitly; but,
not for printf() in <stdio.h>?

Because both these functions are implemented as part of the "Single UNIX Specification". This history of this standard is interesting, and is known by many names (IEEE Std 1003.1, X/Open Portability Guide, POSIX, Spec 1170).

This standard, specifically separates out the "Standard C library" routines from the "Standard C Mathematical Library" routines (page 277). The pertinent passage is copied below:

Standard C Library

The Standard C library is automatically searched by
cc to resolve external references. This library supports all of the
interfaces of the Base System, as defined in Volume 1, except for the
Math Routines.

Standard C Mathematical Library

This library supports
the Base System math routines, as defined in Volume 1. The cc option
-lm is used to search this library.

The reasoning behind this separation was influenced by a number of factors:

  1. The UNIX wars led to increasing divergence from the original AT&T UNIX offering.
  2. The number of UNIX platforms added difficulty in developing software for the operating system.
  3. An attempt to define the lowest common denominator for software developers was launched, called 1988 POSIX.
  4. Software developers programmed against the POSIX standard to provide their software on "POSIX compliant systems" in order to reach more platforms.
  5. UNIX customers demanded "POSIX compliant" UNIX systems to run the software.

The pressures that fed into the decision to put -lm in a different library probably included, but are not limited to:

  1. It seems like a good way to keep the size of libc down, as many applications don't use functions embedded in the math library.
  2. It provides flexibility in math library implementation, where some math libraries rely on larger embedded lookup tables while others may rely on smaller lookup tables (computing solutions).
  3. For truly size constrained applications, it permits reimplementations of the math library in a non-standard way (like pulling out just sin() and putting it in a custom built library.

In any case, it is now part of the standard to not be automatically included as part of the C language, and that's why you must add -lm.

痕至 2024-10-25 01:28:30

我仍然遇到添加 -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,它就无法工作。顺序很重要。您必须指定 -lm last,如下所示:

gcc mtest.c -o mtest.o -lm

链接没有问题。

因此,您必须在最后指定库。

I still have the problem with -lm added:

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

I discovered recently that it does not work if you specify -lm first. The order matters. You must specify -lm last, like this:

gcc mtest.c -o mtest.o -lm

That links without problems.

So, you must specify the libraries at the end.

另类 2024-10-25 01:28:30

您需要链接数学库 libm:

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

You need to link with the math library, libm:

$ gcc -Wall foo.c -o foo -lm 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文