gcc与静态库链接

Ste*_*n A 6 c gcc

我正在读一本名为"海湾合作委员会简介"的书,希望得到一些澄清.在书中表明,下面的代码将导致一个错误,但是当我编译,它建立并运行完美:

#include <math.h>
#include <stdio.h>
int main (void) {
  double x = sqrt (2.0);
  printf ("The square root of 2.0 is %f\n", x);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我引用了一本书" 试图从这个源文件单独创建一个可执行文件导致编译器在链接阶段给出错误: "

$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function `main':
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference 
  to `sqrt'
Run Code Online (Sandbox Code Playgroud)

本书给出的解决方案是你应该包含数学库' libm.a ' 的路径,如下所示:

$ gcc -Wall calc.c /usr/lib/libm.a -o calc
Run Code Online (Sandbox Code Playgroud)

必须指定我们在程序中使用的内置库的路径是非常不方便的.我可以理解将路径添加到我自己的自定义库的原因,但libm.a内置于gcc中.虽然这本书已经很老了(2004年出版),但更新现代版本的gcc会有什么变化,所以我们不需要包含libm.a的路径?

*更新*

我注意到taskinoor给出的答案演示了更新的代码,如果在编译时未知传递给sqrt()的值,则需要使用-lm标志.

我使用VS学习了C/C++,但我现在的目标是学习和使用gcc.我有Visual Studio 2013和VS编译器/链接器似乎不那么挑剔.例如,我可以编译几乎任何简单的程序,而无需指定神秘的编译器标志.

我正在学习KUBUNTU 16.04.1附带的gcc 5.4版本

tas*_*oor 6

sqrt (2.0);

现代GCC很好地确定您正在尝试查找常量的平方根,因此它能够在编译时计算出它.您的目标代码不包含实际调用sqrt.

如果你使用一个scanf在运行时输入的变量,那么它将不会链接libm.

int main() {
    double x;

    scanf("%lf", &x);
    printf("%lf\n", sqrt(x));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

libm在Ubuntu 14.04上没有gcc 4.8.4,结果如下:

/tmp/ccVO2fRY.o: In function `main':
sqrt.c:(.text+0x2c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

但是,如果我把一个常数而不是x像你的例子那么它没有链接libm.

PS:我不知道确切的版本,因为GCC能够做到这一点.希望其他人可以指出这一点.