3

以下代码在 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() 的参数,那么程序正在编译和执行。为什么在第一种情况下会抛出错误。

4

5 回答 5

4

这是一个链接器错误。

链接器缺少sqrt(). 它驻留在图书馆中libm

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

于 2013-04-01T12:20:24.947 回答
3

的实现sqrt()可在数学库libm.

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

gcc rms.c -lm

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

SYNOPSIS
       #include <math.h>

       double sqrt(double x);

       Link with -lm.
于 2013-04-01T12:29:01.957 回答
2

您必须与libm

gcc rms.c -lm

如果您想了解更多说明Linking with external libraries

祝你好运 ;)

于 2013-04-01T12:20:48.397 回答
2

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

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

于 2015-07-01T01:42:44.247 回答
0

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

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

这是一种不断折叠的形式。

于 2019-09-03T11:38:36.553 回答