4

我有两段代码,除了一行之外都相同。一个程序编译失败,另一个程序编译成功。当我执行 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=%f\n",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=%f\n",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

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

4

2 回答 2

2

您没有与数学库链接。如果您正在使用gcc,您需要-lm在最后通过。

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

于 2013-10-04T18:54:06.640 回答
1

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

GCC 包括标准 C 库中许多函数的内置版本。即使您指定了 -fno-builtin 选项,前缀为 __builtin_ 的版本始终被视为与 C 库函数具有相同的含义。(请参阅 C 方言选项)其中许多功能仅在某些情况下进行了优化;如果它们在特定情况下未优化,则会发出对库函数的调用。

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

call    sin
于 2013-10-04T18:55:18.357 回答