gcc和数学的奇怪行为?

gcc和数学的奇怪行为?,c,math,pow,C,Math,Pow,我一直在尝试构建一些使用数学函数的代码(例如,pow) 包含math.h,并且在构建期间使用标志-lm 当像这样调用编译时(-lm标志在命令的开头),它失败了,表示存在对pow的未定义引用: gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o

我一直在尝试构建一些使用数学函数的代码(例如,
pow

包含
math.h
,并且在构建期间使用标志
-lm

当像这样调用编译时(
-lm
标志在命令的开头),它失败了,表示存在对
pow
的未定义引用:

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder
main.o: In function `get_sn_motif_id':
main.c:(.text+0x28d): undefined reference to `pow'
-lm
标志放在comand的末尾时,它就工作了

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm

这正常吗?

是的,正常。对于许多链接器,指定对象文件和库的顺序很重要

引述:

链接器的传统行为是在命令行上指定的库中从左到右搜索外部函数。这意味着包含函数定义的库应该出现在使用它的任何源文件或目标文件之后。这包括使用快捷方式
-l
选项指定的库,如以下命令所示:

$gcc-Wall calc.c-lm-o calc(正确顺序)

这种行为很常见,但决不是普遍的。如有疑问,最好查阅链接器手册。例如,在我的Ubuntu系统上
manld
声明:

   -l namespec
   --library=namespec

       ...

       The linker will search an archive only once, at the location where
       it is specified on the command line.  If the archive defines a
       symbol which was undefined in some object which appeared before the
       archive on the command line, the linker will include the
       appropriate file(s) from the archive.  However, an undefined symbol
       in an object appearing later on the command line will not cause the
       linker to search the archive again.
换句话说,此链接器的行为方式与
gcc
一书中所述的方式相同。

链接器的传统行为是在命令行上指定的库中从左到右搜索外部函数。这意味着包含函数定义的库应该出现在使用它的任何源文件或目标文件之后

我想你也看到了同样的行为

请注意,它还进一步指出

大多数现代链接器搜索所有库,而不考虑顺序,但最好遵循从左到右排序库的惯例。


尽管应该提到,这不适用于共享库(至少对于gcc),但它们可以出现在命令行的任何位置。所以人们就这么做了。然而,最近这种情况发生了变化,gcc现在在许多平台上将
--as needed
标志应用于链接器,因此对共享库的效果也是一样的。我没注意到这是个老问题。