那么,我认为我的问题有点有趣,我想了解我的Ubuntu盒子里发生了什么。
我用gcc -lm -o useless useless.c
编译并链接了gcc -lm -o useless useless.c
下面gcc -lm -o useless useless.c
无用的代码:
/*File useless.c*/ #include <stdio.h> #include <math.h> int main() { int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100))); return(0); }
到现在为止还挺好。 但是当我改变为:
/*File useless.c*/ #include <stdio.h> #include <math.h> int main() { int freq = 440; int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100))); return(0); }
而我尝试使用相同的命令行,gcc响应编译:
/tmp/cctM0k56.o: In function `main': ao_example3.c:(.text+0x29): undefined reference to `sin' collect2: ld returned 1 exit status
并停止。 发生什么事? 为什么我不能这样编译?
我也尝试了一个sudo ldconfig -v
没有成功。
提前致谢!
卢卡斯。
这里有两件不同的事情。
对于第一个例子,编译器不会产生对sin
的调用。 它认为参数是一个常量表达式,所以它用表达式的结果替换了sin(...)
调用,并且不需要数学库。 没有-lm
就可以工作。 (但是你不应该指望这一点;当编译器执行这种优化时,并不总是很明显。)
(如果你编译
gcc -S useless.c
并看看useless.s
,生成的汇编语言列表,你可以看到没有sin
的呼声。)
对于第二个示例,您确实需要-lm
选项 – 但它需要位于命令行的末尾,或者至少需要useless.c
需要它的文件( useless.c
)之后:
gcc -o useless useless.c -lm
要么
gcc useless.c -lm -o useless
链接器按顺序处理文件,跟踪每个文件的未解析符号( sin
,由useless.o
),然后在查看它们的定义时解析它们。 如果你先把-lm
放进去,在处理数学库的时候就没有未解决的符号; 当它看到useless.o
sin
时,它已经太迟了。