C 关于链接数学库的几个问题

C 关于链接数学库的几个问题,c,gcc,math.h,C,Gcc,Math.h,我正在编写一个c项目,它必须使用math.h中定义的pow函数。 当我尝试创建项目时,gcc给出了以下链接错误: 对“pow”的未定义引用 我知道-lm选项必须添加到我的链接指令中,但仍然有几个问题困扰着我 Q1:当我将两个常量传递给pow函数时,链接在没有-lm的情况下成功。为什么? Q2:-lm位于链接指令的末尾或开头会产生不同的结果。gcc-lm$(OBJS)-oexbin是错误的,但是gcc$(OBJS)-oexbin-lm是正确的。为什么? 我使用Ubuntu11.10和GCC4.4.

我正在编写一个c项目,它必须使用math.h中定义的pow函数。 当我尝试创建项目时,gcc给出了以下链接错误: 对“pow”的未定义引用

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

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

Q2:-lm位于链接指令的末尾或开头会产生不同的结果。gcc-lm$(OBJS)-oexbin是错误的,但是gcc$(OBJS)-oexbin-lm是正确的。为什么?

我使用Ubuntu11.10和GCC4.4.4


谢谢!请原谅我的蹩脚英语。

我无法回答问题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
。简而言之,您总是希望最后链接库函数。

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


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

使用标准math.h不需要任何特殊的链接器选项。而
pow
接受两个参数,这就是为什么它在正确使用它时不会给您错误。