当我尝试从终端编译这个简单的代码时:
#include<stdio.h>
int main(void)
{
printf("%f\n",sqrt(10));
return 0;
}
使用
gcc main.c
命令,它被编译,a.out给出了正确的答案。这意味着数学函数被添加到C标准库中,并自动链接。
但是如果在Eclipse IDE中编译相同的代码而不向属性添加任何库,则会给出未定义的引用错误。这意味着数学函数不是C标准库的一部分。
真相是什么?
答案 0 :(得分:6)
您可能在这里看到constant folding,其中在数学函数调用中使用常量将导致编译器计算函数并省略对数学库的调用。
如果我们查看Other Built-in Functions Provided by GCC的文档说明(强调我的):
GCC包含标准C库中许多功能的内置版本。即使您指定-fno-builtin选项,前缀为_ builtin 的版本也始终被视为与C库函数具有相同的含义。 (参见C方言选项)许多这些功能仅在某些情况下得到优化; 如果在特定情况下未进行优化,则会发出对库函数的调用。
如果我们查看使用以下代码的slightly modified live example:
#include <stdio.h>
#include <math.h>
int main(void)
{
printf("%d\n",(int)sqrt(25));
return 0;
}
我们看到gcc
生成的以下程序集:
movl $5, %esi
movq %rax, %rdi
movl $0, %eax
call printf
所以我们看到5
被移入esi
,x64 abi中的sqrt(25)
是调用函数的第二个参数,是sqrt
没有调用的结果到#include <math.h>
。
注意你遗失了:
-std
更新
内置插件是一个gcc extension,上面的内置链接解释了哪些模式在哪种模式下使用,它们都应具有与标准功能相同的含义。
如果您担心您的代码符合标准,那么您可以查看手册的Options Controlling C Dialect部分。您可以使用-pedantic
指定要遵守的标准,并使用-pedantic-errors
在使用不符合标准的功能时启用警告,或使用gcc -std=c99 -pedantic
发出警告错误。例如,使用
-fno-builtin
当您使用符合 C99 标准的功能时,会生成警告,例如zero length arrays。
我们还可以使用{{1}}来禁用一些内置文件,文档说:
无法识别不以_ builtin 作为前缀开头的内置函数。有关受影响的功能的详细信息,请参阅GCC提供的其他内置函数,包括那些在使用严格ISO C一致性的-ansi或-std选项时不是内置函数的函数,因为它们没有ISO标准含义。 [...]
答案 1 :(得分:0)
在某些编译器上,标准库函数默认情况下启用。在编译
int main(){
printf("Hello World");
return 0;
}
这个代码在GCC 4.7.1上汇编了警告:
[Warning] implicit declaration of function 'printf' [-Wimplicit-function-declaration]
[Warning] incompatible implicit declaration of built-in function 'printf' [enabled by default]