谁能解释它们是什么以及我为什么需要它们?如果我需要使用内在函数,我会构建什么样的应用程序?
4 回答
内在函数是编译器在可能的情况下直接实现的函数,而不是链接到函数库提供的实现。
一个常见的例子是strncpy()
。
对于短字符串,对 进行函数调用strncpy()
(包括设置带有返回地址的“堆栈帧”)将比实际复制字节消耗更多时间。更糟糕的是,对 CPU 预取缓冲区的影响会使 CPU 执行停滞几个时钟周期。
相反,内部函数由编译器实现,而不是函数调用。在 的示例中,字节复制代码直接在调用strncpy()
的地方发出。strncpy()
与此strncpy()
示例类似,如果满足所需的约束,每个内部函数都直接作为内联代码实现。
内部函数的非内部副本通常仍存在于标准库中,以防需要函数的地址。
与内联函数相比,内部函数由编译器提供。在 C 程序的源代码中没有编写内部函数的地方,也没有必须链接到的库实现。内联函数的不同之处在于编译器读取内联函数的源代码,但相似之处在于稍后它可以将内联函数的编译翻译直接发送到目标代码中,从而省略了函数调用的开销。
简而言之,内在函数和内联函数之间的实际区别在于,即使您没有#include
包含函数声明的所需头文件,内在函数也是“存在的”。对于内联函数,具有函数声明的头文件必须首先是#include
'd(或以其他方式声明)。
通常,“内在函数”是指内置函数——即编译器可以/将生成内联而不是调用库中的实际函数的大多数标准库函数。例如,memset(array1, 10, 0)
可以为 x86 编译类似的调用:
mov ecx, 10
xor eax, eax
mov edi, offset FLAT:array1
rep stosb
像这样的内在函数纯粹是一种优化。“需要”内在函数很可能是编译器支持内在函数的情况,这些内在函数允许您生成编译器不能(或通常不会)直接生成的代码。举个明显的例子,相当多的 x86 编译器都有“MMX Intrinsics”,让您可以使用“函数”,这些“函数”实际上只是 MMX 指令的直接表示。
编译器将内部函数公开为本身不属于任何库的函数。
您可能使用最多的是汇编内在函数,编译器将其视为它们所代表的机器指令。例如,您可以在需要利用编译器不会自动生成的特定 CPU 指令的代码中使用它们,并且您不一定需要完整的内联汇编部分。
“内在”是编译器识别和实现的语言的那些特性,而不需要程序声明它们。编译器可能会(也可能不会)链接到运行时库以执行操作。例如,在 C++ 中,结构复制操作是隐式的:
struct {
int a;
char b [100];
long c [27];
} s, t;
...
s = t; // this statement copies hundreds of bytes, likely with a rtl call
其他示例包括 Fortran 等语言,其中隐式支持复杂类型,而超越(正弦、正切等)函数不需要也不能声明。PHP、Javascript、Ruby 等具有数百个内在函数,例如创建和搜索数组、执行正则表达式匹配等。
至于您的其他问题,唯一的区别是它们是否需要声明。例如,使用超越函数的 C++ 程序必须包含数学库声明:
#include <math.h>
没有特定的依赖于内在函数的应用程序模式;这对编译器编写者和程序员来说只是一个重要的问题。