我正在编写一个必须使用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。
谢谢!请原谅我的英语池。
答案 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_a
和func_b
正确关联到可执行文件中,您必须将其gcc func_b func_a -o exec
关联,因为func_b
使用func_a
。简而言之,您总是希望最后链接库函数。