繁体   English   中英

我在我的C程序中使用了pow()函数,但没有链接到-lm它仍然有效。 为什么?

[英]I used pow() function in my C program but did not link to -lm it still worked. Why?

我正在读一本关于海湾合作委员会的书。 它表示,对于任何C程序,默认情况下只链接标准库。 由于pow()不在标准库中,我将不得不使用-lm标志链接到它。 但是,当我编译时,我只是使用:

gcc hello.c -o hello

它仍然有效..

还有另一个类似的问题,书中还说如果你有printf("%f\\n", 4); 在您的C程序中,如果编译WITHOUT -Wall选项,则不会发出警告。 但是,我尝试在没有-Wall选项的情况下编译它,但我仍然收到警告:

hello.c:6:2:警告:格式'%f'需要类型为'double'的参数,但参数2的类型为'int'[-Wformat]

为什么是这样? 这本书说我必须提供-lm-Wall才能使我的程序编译并得到警告但是我没有使用它们中的任何一个但是我仍然编译了程序并得到了警告?

谢谢!

基于一些实验的更多信息。

考虑这个程序:

#include <stdio.h>
#include <math.h>
int main(void) {
#ifdef CONSTANT
    double x = pow(2.0, 10.0);
#else
    double expon = 10.0;
    double x = pow(2.0, expon);
#endif
    printf("x = %f\n", x);
    return 0;
}

在Ubuntu上,当我用它编译它时

$ gcc c.c -o c

它抱怨未提及对pow引用; 添加-lm可以纠正它。

但是这个:

$ gcc -DCONSTANT c.c -o c

编译和链接没有错误,用常量1024.0替换pow()调用。 但是这个:

$ gcc -fno-builtin -DCONSTANT c.c -o c

再次抱怨对pow的未定义引用。

结论:只有在编译时才能确定结果时,gcc才使用pow的内置实现。 否则它会生成对pow()函数的显式调用,这需要与-lm链接。

另请注意,这取决于C库的组织方式(库是单独提供的;它不是gcc的一部分)。 在Cygwin上,使用newlib而不是Ubuntu上使用的glibc ,不需要-lm选项; 显然,数学例程是标准库的组成部分,而不是单独提供。 (Cygwin上的gcc仍然接受-lm选项。)

GCC提供了几个标准库函数作为内置函数:

GCC提供了除上述功能之外的大量内置功能。 其中一些内容用于处理异常或可变长度参数列表,因此它们可能会不时更改,因此不会在此处记录; 我们不建议一般使用这些功能。

其余功能用于优化目的。

如果你看一下内置插件列表,你会发现pow就是其中之一。

如果将-fno-builtin添加到编译器选项中,则应该得到您期望的链接器错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM