关于连接数学库的一些问题

时间:2012-04-10 03:36:39

标签: c gcc math.h

我正在编写一个必须使用math.h中定义的pow函数的c项目。 当我尝试制作项目时,gcc给出了以下链接错误: 未明确引用`pow'。

我知道-lm选项必须添加到我的链接指令中,但仍有几个问题令我困惑。

Q1:当我将两个常量传递给pow函数时,链接成功而没有-lm。为什么呢?

Q2:-lm在链接指令的结尾或开始处产生不同的结果。 gcc -lm $(OBJS)-o exbin错误,但是gcc $(OBJS)-o exbin -lm是正确的。为什么呢?

我使用的是ubuntu 11.10和gcc 4.4.4。

谢谢!请原谅我的英语池。

2 个答案:

答案 0 :(得分:1)

编译器知道pow(3, 4)或其他什么,并通过在编译时计算结果来优化程序,因此它不需要链接和运行时的库。

链接器不会从库中添加内容,除非它知道它需要它。使用静态库,这是完全正确的。对于共享库,某些版本的编译器会记录所有已读取的共享库中的所有符号,即使在扫描库时不需要它们也是如此。如果在扫描时需要至少一个符号,则更新版本仅接受共享库。当库首先出现时,唯一需要的符号是main()(这就是为什么main()被指定为托管环境的起点),因此数学库被忽略,因为其中没有符号那是必要的。

答案 1 :(得分:0)

我无法回答问题1(这似乎很奇怪),但就问题2而言,gcc -lm $(OBJS) -o exbin不起作用的原因是因为您必须按使用顺序链接事物。最好通过示例解释:

/* File func_a.h */
/* Declare func_a */
void func_a();

/* File func_a.c */
#include "func_a.h"
void func_a()
{
    /* do stuff */
}

/* File func_b.c */
#include "func_a.h"
void func_b()
{
    /* Call func_a */
    func_a();
}

要将func_afunc_b正确关联到可执行文件中,您必须将其gcc func_b func_a -o exec关联,因为func_b使用func_a。简而言之,您总是希望最后链接库函数。