当我尝试从终端编译这个简单的代码时:
#include<stdio.h>
int main(void)
{
printf("%f\n",sqrt(10));
return 0;
}
使用
gcc main.c
命令,它被编译并且 a.out 给出正确的答案。这意味着数学函数被添加到自动链接的 C 标准库中。
但是如果在 Eclipse IDE 中编译相同的代码而不向属性添加任何库,则会出现 undefined reference 错误。这意味着数学函数不是 C 标准库的一部分。
什么是真相?
最佳答案
您可能会看到 constant folding在这里,在数学函数调用中使用常量将导致编译器计算函数并忽略对数学库的调用。
如果我们查看 Other Built-in Functions Provided by GCC 的文档说(强调我的):
GCC includes built-in versions of many of the functions in the standard C library. The versions prefixed with _builtin are always treated as having the same meaning as the C library function even if you specify the -fno-builtin option. (see C Dialect Options) Many of these functions are only optimized in certain cases; if they are not optimized in a particular case, a call to the library function is emitted.
如果我们看这个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>
更新
内置函数是一个 gcc extension上面的内置链接解释了哪些在哪种模式下使用,它们应该与标准函数具有相同的含义。
如果您担心您的代码是否符合标准,那么您可以查看 Options Controlling C Dialect手册的一部分。您可以使用 -std
来指定您想要遵守的标准,并使用 -pedantic
在您使用不符合标准或 的功能时启用警告>-pedantic-errors
使警告成为错误。所以例如使用
gcc -std=c99 -pedantic
当您使用符合 C99 标准的功能时会生成警告,例如 zero length arrays .
我们还可以使用 -fno-builtin
来禁用一些内置函数,文档说:
Don't recognize built-in functions that do not begin with _builtin as prefix. See Other built-in functions provided by GCC, for details of the functions affected, including those which are not built-in functions when -ansi or -std options for strict ISO C conformance are used because they do not have an ISO standard meaning. [...]
关于c - 现在 glibc 中包含数学库了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19230849/