【问题标题】:sqrt() function link errorsqrt() 函数链接错误
【发布时间】:2013-04-01 12:16:22
【问题描述】:

以下代码在 Linux 上抛出未定义符号错误。

$ cat rms.c
/* sqrt example */
#include <stdio.h>
#include <math.h>

int main ()
{
  double param, result;
  param = 1024.0;
  result = sqrt (param);
  printf ("sqrt(%lf) = %lf\n", param, result );
  return 0;
}


$ gcc rms.c
/tmp/ccaWecFP.o(.text+0x24): In function `main':
: undefined reference to `sqrt'
collect2: ld returned 1 exit status

如果我用 (double)16 替换 sqrt() 的参数,则程序正在编译和执行。为什么在第一种情况下会抛出错误。

【问题讨论】:

标签: c sqrt


【解决方案1】:

这是一个链接器错误。

链接器缺少sqrt() 的实现。它位于库libm

通过应用选项-lm 告诉 GCC 添加它。

【讨论】:

    【解决方案2】:

    数学库libm中提供sqrt()的实现。

    您必须将您的程序链接到数学库,如下所示:

    gcc rms.c -lm
    

    一个自然的问题是,我怎么知道这个?答案在手册页中。如果我执行“man sqrt”,我会看到以下内容。请注意,概要中提供了链接说明

    SYNOPSIS
           #include <math.h>
    
           double sqrt(double x);
    
           Link with -lm.
    

    【讨论】:

    • 那么为什么程序被编译和链接,如果一个文字被赋予 sqrt() 作为参数,即使我没有与 libm 链接?
    • 它编译成功,因为math.h被正式包含。但是,根据报告的错误消息(“undefined reference to `sqrt' collect2: ld returned 1”),我认为链接没有成功。
    • 将文字作为 sqrt() 的参数,它也被编译、链接和执行!
    【解决方案3】:

    你必须链接libm

    gcc rms.c -lm
    

    如果你想要更多解释Linking with external libraries

    祝你好运;)

    【讨论】:

    • 那么为什么程序被编译和链接,如果一个文字被赋予 sqrt() 作为参数,即使我没有与 libm 链接?
    【解决方案4】:

    正如其他答案所说,您需要传递 -lm 才能链接到包含 sqrt 符号的库。

    它使用常量参数的原因是因为sqrt 被允许作为内置函数实现。当 GCC 看到使用常量参数调用的内置函数时,它可以在编译时计算结果,而不是发出对库中外部函数的调用。

    【讨论】:

      【解决方案5】:

      这里的其他答案讨论了链接错误;如果您将param 替换为常量,我将添加一个关于为什么结果正确的答案。

      GCC 有一个优化,它用内置等效项(例如sqrt)和常量参数(例如16.0)替换函数,并用这些计算的结果(例如4.0)。

      这是常量折叠的一种形式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-05
        • 2012-10-02
        • 2012-06-13
        • 2010-10-31
        相关资源
        最近更新 更多