【问题标题】:Strange behaviour of gcc and math.h? [duplicate]gcc 和 math.h 的奇怪行为? [复制]
【发布时间】:2012-02-18 11:24:40
【问题描述】:

我一直在尝试构建一些使用数学函数的代码(例如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 标志放在命令末尾时,它就起作用了!

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

这正常吗?

【问题讨论】:

  • 糟糕。没有注意到这是一个老问题。

标签: c math pow


【解决方案1】:

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

引用"An Introduction to GCC - for the GNU compilers gcc and g++"

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

$ gcc -Wall calc.c -lm -o calc (correct order)

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

   -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 标志应用于许多平台上的链接器,因此共享库的效果也是一样的。
【解决方案2】:

An Introduction to GCC - for the GNU compilers gcc and g++

中所述

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

我认为你看到了同样的行为。

请注意,它还进一步指出,

大多数现代链接器搜索所有库,无论顺序如何,但最好遵循从左到右排序库的约定。

【讨论】:

    猜你喜欢
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    相关资源
    最近更新 更多