您可能会在这里看到常量折叠,在数学函数调用中使用常量将导致编译器计算函数并一起省略对数学库的调用。
如果我们查看GCC 提供的其他内置函数的文档说(强调我的):
GCC 包括标准 C 库中许多函数的内置版本。即使您指定了 -fno-builtin 选项,带有 _ builtin前缀的版本始终被视为与 C 库函数具有相同的含义。(请参阅 C 方言选项)其中许多功能仅在某些情况下进行了优化;如果它们在特定情况下未优化,则会发出对库函数的调用。
如果我们看一下这个使用以下代码的稍微修改的实时示例:
#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
所以我们看到在x64 abi5
中是调用函数的第二个参数,是根本没有调用的结果。esi
sqrt(25)
sqrt
请注意,您缺少:
#include <math.h>
更新
内置函数是gcc 的扩展,上面的内置链接解释了哪些是在哪种模式下使用的,它们都应该与标准函数具有相同的含义。
如果您担心您的代码是否符合标准,那么您可以查看手册的Options Controlling C Dialect部分。您可以使用-std
来指定要遵守的标准,并-pedantic
在使用不符合标准的功能时启用警告或-pedantic-errors
使警告成为错误。所以例如使用
gcc -std=c99 -pedantic
当您使用符合C99标准的功能(例如零长度数组)时,会生成警告。
我们也可以-fno-builtin
用来禁用一些内置函数,文档说:
不识别不以 _ builtin作为前缀开头的内置函数。有关受影响函数的详细信息,请参阅 GCC 提供的其他内置函数,包括那些在使用严格 ISO C 一致性的 -ansi 或 -std 选项时不是内置函数的函数,因为它们没有 ISO 标准含义。[...]