为什么math.h需要在makefile中链接而不是string.h?

时间:2013-10-22 18:33:59

标签: c linker makefile

我已经将<string.h>全部包括在内,当我为<math.h>添加pow()时,我发现我需要修改我的makefile才能访问pow的定义。

如果我需要包含它们,我也不知道我可以在哪里查找更多库。我随机读取-lm标志(或至少它的m)表示标准c数学库,但我不知道可能调用任何其他标准c库。

我刚看了user/local/lib,我看到的只有:

$ cd /usr/local/lib
$ ls -al
drwxr-xr-x  3 root root  4096 Apr 25  2012 .
drwxr-xr-x 10 root root  4096 Apr 25  2012 ..
drwxrwsr-x  4 root staff 4096 Oct 14 10:19 python2.7

4 个答案:

答案 0 :(得分:4)

string.h是标准库模块的标头引用,但由于历史原因,math.h不是标准库模块的标头引用。编译程序时,链接器中通常只包含标准库。

在某个时间点,可以将libm.so math.h实现替换为针对内存,CPU性能等进行了更优化的其他实现。实际上,没有一个libm.so“默认“实施。但是,大多数系统至少提供了实现。该实现位于默认库位置libm.so,并将与-lm链接。

如果你知道自己可以使用更快(可能甚至以不太准确为代价)的库,那么你就可以覆盖系统提供的math.h libm.so实现

早期的CRAY系统(我没有在一个上工作)确实优化了一些数学实现,没有做正确的“完整”数学运算,理解为了获得100%正确答案,你将“完成”由于计算中的有效位数,通常不重要的代码的汇编操作。 (根据我对华盛顿特区密码学博物馆展览的理解)

多个实现的问题在于您现在可以选择,并且标准C库的结构不是为您提供实现选择。

答案 1 :(得分:2)

为了向您提供有关帖子另一方面的更多信息,要查找您机器上库的位置,将取决于操作系统。由于看起来您正在使用带有bash的操作系统,您会在/usr/usr/local文件夹中找到大多数库(也许我不应该说最多,但它是许多库的默认安装位置)我用过,比如提升)。这不是c ++库往往安装的位置。

我的c ++库位于标有lib的文件夹中,这使得使用find工具轻松搜索。像find / -iname "*lib*" 2>/dev/null这样的东西可以帮助您找到您可能已安装库的任何位置,您需要告诉链接器。 (如果要2>/dev/null命令,可以忽略sudo

我最近遇到了很多麻烦,让我的IDE能够很好地使用boost,所以希望这有助于您将来连接库时遇到的任何麻烦。

编辑:我想添加一些关于如何告诉IDE关于库的信息。使用find工具,查找名为include的所有文件夹将导致任何应包含在IDE编译器Additional Include Directories中的文件夹(不是所有名为include的文件夹,我应该澄清,但这将有助于查找具有所需名称和特定文件夹的任何文件夹,例如在搜索结果中查看/usr/local/include/boost。我之前提到过如何查找的库将添加到Additional Library Directories下的链接器部分中,以便他们知道在哪里专门查找这些库。

编辑2:要提供有关在Windows上找到适当文件的位置的一些信息,搜索会有点困难。似乎没有真正的开发人员安装的“标准”位置(如果它可能是当前用户的主目录,但这远远不是唯一使用的地方)。此外,Windows上的find功能并不简单或有用(在我看来)。最重要的是,特别是对于c ++文件,它将完全基于您获取文件的方式。例如,如果您使用的是Visual Studio,它们位于Visual Studio的c ++部分的文件夹内(即我的机器上是C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\),但如果您使用的是可以从MinGW获取的文件,它将会在不同的位置。我唯一的建议是在你选择的位置创建一个文件夹(我在C :)中直接使用了一个文件夹来手动安装你添加到系统中的所有东西。

例如,

Boost允许在安装时轻松更改默认安装路径。大多数(我更熟悉,几乎所有这里都说)创建的工具将具有此功能,尤其是在Windows上。否则,搜索您添加的每个实用程序的特定默认位置或学习使用Windows提供的find实用程序是可行的选项。

答案 2 :(得分:1)

标准C库函数都在libc中定义,您无需将其链接到您的程序,因为链接器时链接器会自动完成它。唯一的例外是数学函数。它们被放在一个名为libm的独立库中。由于与UNIX上的Fortran编译器相关的历史原因,它们被放在一个单独的库中(我没有任何来源支持这种说法)。

答案 3 :(得分:0)

数学库的实现(通常)分为两部分。

<math.h>是一个头文件,通常为/usr/include/math.h。它的C源代码告诉编译器如何生成对pow和其他函数的调用。它应该是默认可用的;你只需要#include <math.h>,编译器就会知道在哪里找到它。 (所以你的头衔有点误导。)

<math.h>中声明 的函数已在库文件中实现,其中包含可编译的可执行代码,可以链接到您的程序中(在编译之后) )。出于历史原因,该库通常默认情况下搜索,您必须指定一个额外的-lm选项,以告知链接器在哪里找到它。 (这被广泛认为是一个错误;另一方面,默认情况下不搜索数学库可以使链接速度更快,大多数C程序不使用数学库。)