Zes*_*ang 3 c compiler-construction gcc
我正在读一本关于海湾合作委员会的书.它表示,对于任何C程序,默认情况下只链接标准库.由于pow()
不在标准库中,我将不得不使用-lm
标志链接到它.但是,当我编译时,我只是使用:
gcc hello.c -o hello
Run Code Online (Sandbox Code Playgroud)
它仍然有效..
还有另外一个类似的问题,本书还说如果你有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;
}
Run Code Online (Sandbox Code Playgroud)
在Ubuntu上,当我用它编译它时
$ gcc c.c -o c
Run Code Online (Sandbox Code Playgroud)
它抱怨未定义的引用pow
; 添加-lm
纠正它.
但是这个:
$ gcc -DCONSTANT c.c -o c
Run Code Online (Sandbox Code Playgroud)
编译和链接没有错误,用pow()
常量替换调用1024.0
.但是这个:
$ gcc -fno-builtin -DCONSTANT c.c -o c
Run Code Online (Sandbox Code Playgroud)
再次抱怨未定义的引用pow
.
结论:pow
只有在编译时才能确定结果时,gcc才使用内置实现.否则它会生成对pow()
函数的显式调用,这需要链接-lm
.
另请注意,这取决于C库的组织方式(库是单独提供的;它不是gcc的一部分).在Cygwin上,使用newlib而不是Ubuntu上使用的glibc,-lm
不需要选项; 显然,数学例程是标准库的组成部分,而不是单独提供.(Cygwin上的gcc仍然接受该-lm
选项.)
GCC提供了几个标准库函数作为内置函数:
GCC提供了除上述功能之外的大量内置功能.其中一些内容用于处理异常或可变长度参数列表,因此它们可能会不时更改,因此不会在此处记录; 我们不建议一般使用这些功能.
其余功能用于优化目的.
如果你看一下内置插件列表,你会发现它pow
就是其中之一.
如果添加-fno-builtin
到编译器选项,则应该得到您期望的链接器错误.