math.h 链接器错误在 C 中使用 sin()



>我有两段代码,除了一行之外,其他代码段都相同。一个程序编译失败,另一个程序成功。当我执行 cc 来编译代码时,我确实链接了数学库。

我正在使用double sin(double)功能。 它显然是在math.h中定义的,尽管我查看了/usr/include/math.h,没有发现对sin()函数的引用。

见 http://www.gnu.org/software/libc/manual/html_mono/libc.html#Trig-Functions

sin()函数在我给出的一个代码段中确实有效,但在另一个代码段中不起作用。

//Successful program - demo1.c
#include <stdio.h>
#include <math.h>
int main (void)
{
    double input, sine_A; 
    input = 6.2830;
    sine_A = sin(6.2830);
    printf("sine=%fn",sine_A);
    return 0;
}

这是失败的程序:

//Failed program - demo2.c
#include <stdio.h>
#include <math.h>
int main (void)
{
    double input, sine_A;
    input = 6.2830;
    sine_A = sin(input);
    printf("sine=%fn",sine_A);
    return 0;
}
$ cc -lm demo2.c
/tmp/ccnpIWZd.o: In function `main':
demo2.c:(.text+0x1c): undefined reference to `sin'
collect2: ld returned 1 exit status

这让我觉得有点愚蠢,或者至少,多年来我觉得我错过了一些东西。

您没有链接到数学库。如果您使用的是gcc则需要在最后传递-lm

那么为什么第一个例子有效呢?我可以推测这种情况正在发生,因为您直接在双精度文本上调用sin并且gcc可以在不需要 libm 的情况下发挥自己的魔力 - 它可以简单地直接计算它并完全用结果替换调用。

-lm需要位于命令的末尾,很可能在第一种情况下,编译器正在优化对sin的调用,因此不需要链接到库。这称为常量折叠,例如,我们可以在 GCC 提供的其他内置函数的gcc文档中看到 说(强调我的(:

GCC 包括许多函数的内置版本 标准 C 库。以 __builtin_ 为前缀的版本始终 被视为与 C 库函数具有相同的含义,即使 指定 -FNO 内置选项。(请参阅 C 方言选项(许多 这些功能仅在某些情况下进行优化;如果不是 在特定情况下进行了优化,对库函数的调用是 排放。

这是一个现场演示,我们可以从文字大小写中的程序集中看到gcc它优化了对sin的调用,这个演示显示了非文字大小写,我们在程序集中看到:

call    sin

最新更新