C - 对"sqrt"的未定义引用,即使使用'-lm'

Ale*_*oux 10 c gcc math.h ld

我尝试在C中编译一个需要"math.h"的库,这里是.c文件的开头:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h> 
#include "sparse_matrix.h"
...
Run Code Online (Sandbox Code Playgroud)

我用这个命令编译:

gcc -c ./sparse_matrix.c -o sparse_matrix.o -lm -Wall -pedantic -std=c99 -g -O
Run Code Online (Sandbox Code Playgroud)

但即使文件后面的#include完成和标志-lm(我已尝试在行尾但没有改变)我仍然得到错误: undefined reference to « sqrt » collect2: error: ld returned 1 exit status

谷歌搜索一小时后,我没有得到它.我在ubuntu 14.10(utopic unicorn)下使用gcc 4.9.提前感谢您的帮助!

pax*_*blo 11

我不认为这你正在运行的命令(好吧,它可能是其中之一,但它肯定不是导致你的错误的命令).

告诉它只创建目标文件的-c选项gcc(并且您专门将输出发送到sparse_matrix.o目标文件而不是可执行文件).

在这种情况下,根本应该调用链接器.

事实上,假人sparse_matrix.c:

#include <math.h>
int main(void) {
    return (int)(sqrt(16.0));
}
Run Code Online (Sandbox Code Playgroud)

你的命令工作正常,当我完成以下过程:

pax> gcc -o sparse_matrix sparse_matrix.o -lm
pax> ./sparse_matrix
pax> echo $?
4
Run Code Online (Sandbox Code Playgroud)

你可以看到它也运行得很好.

可能是您-lm从实际链接阶段中脱离链接器标志(例如),这将导致此问题.它们应该对编译阶段没有影响(除非它们影响编译链接阶段但-l不是其中之一).

并且,通过"离开",我还包括"错位"的可能性.一些链接器在处理库的方式上是位置的,因为如果它们在列出它们的位置满足未定义的符号,它们将仅从库中提取对象.

所以,命令:

linker sparse_matrix.o -lm ...
Run Code Online (Sandbox Code Playgroud)

会工作,因为该.o文件引入了一个不满意的引用sqrt,这是满意的libm.如果您的链接器位置的,那么:

linker -lm sparse_matrix.o ...
Run Code Online (Sandbox Code Playgroud)

不起作用,因为在处理时libm,没有不满意的符号,所以没有提取任何东西.sqrt然后该点之后引入未定义的引用,并且没有其他对象或库来满足它.

我不知道是否ld或者gcc链接器阶段有这种限制,我只是提出了一些需要注意的可能性.