0

我正在编写 ac 项目,它必须使用 math.h 中定义的 pow 函数。当我尝试制作该项目时,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。

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

4

2 回答 2

1

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

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

于 2012-04-10T03:54:02.627 回答
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. 简而言之,您总是希望最后链接您的库函数。

于 2012-04-10T03:49:01.400 回答