内联函数说明符
内联函数是指编译器将代码从函数定义直接复制到调用函数的代码中,而不是在内存中创建单独的指令集。 可以直接将函数主体的修改副本替换为函数调用,而不是将控制转移到函数代码段和从函数代码段转移。 这样就避免了函数调用的性能开销。 使用 inline 说明符只是对编译器的建议,即可以执行内联扩展; 编译器可以随意忽略该建议。
除了 ,任何函数都可以通过 函数说明符进行声明或定义。 main inline 静态局部变量不允许在嵌入式函数的主体中定义。
在类声明中实现的C++函数会自动定义为内联函数。 可以使用 inline 函数说明符来声明或定义在类声明外部声明的常规 C++ 函数和成员函数 ( main除外)。 在嵌入式函数体内定义的静态局部变量和字符串字面量在翻译单元中被视为同一对象;详情请参阅嵌入式函数的链接。
inline int add(int i, int j) { return i + j; }使用 inline 说明符不会更改函数的含义。 但是,函数的内联扩展可能不会保留实际自变量的求值顺序。对内联函数进行编码的最有效方法是将内联函数定义放在头文件中,然后将头包含在包含对要内联的函数的调用的任何文件中。
inline 说明符由以下关键字表示:
inline关键词在编译时与 xlc 或 c99-qlanglvl=stdc99 或 -qlanglvl=extc99 选项或 -qkeyword=inline。__inline__(或__inline) 关键字在所有语言级别都可识别; 但是,请参阅下面的 内联函数的链接 以获取此关键字的语义。
inline、 和 关键词在所有语言级别均被识别。__inline__inline__
内联函数的链接

foo ,也会将文件 a.c 中的 foo 和文件 b.c 中的 foo 视为单独的函数: 生成两个函数主体,并在内存中分配两个不同的地址:// a.c
#include <stdio.h>
inline int foo(){
return 3;
}
void g() {
printf("foo called from g: return value = %d, address = %p\n", foo(), &foo);
}
// b.c
#include <stdio.h>
inline int foo(){
return 3;
}
void g();
int main() {
printf("foo called from main: return value = %d, address = %p\n", foo(), &foo);
g();
}
编译的程序的输出为:foo called from main: return value = 3, address = 0x10000580
foo called from g: return value = 3, address = 0x10000500g 调用 foo 可能返回 6 或 3:// a.c
#include <stdio.h>
inline int foo(){
return 6;
}
void g() {
printf("foo called from g: return value = %d\n", foo());
}
// b.c
#include <stdio.h>
int foo(){
return 3;
}
void g();
int main() {
printf("foo called from main: return value = %d\n", foo());
g();
}
同样,如果将函数定义为 extern
inline,或者将 inline 函数重新声明为 extern,那么该函数将成为常规的外部函数,并且不会直接插入。
如果您指定了 关键字,并带有下划线,则编译器将使用GNU C语义的内联函数。 __inline__ 与 C99 语义相反,定义为 __inline__ 的函数仅提供外部定义; 定义为 static __inline__ 的函数提供具有内部链接的内联定义 (如 C99中所示); 定义为 extern __inline__的函数在启用优化的情况下进行编译时,允许同一函数的内联定义与外部定义共存。 有关内联函数 GNU C 实现的更多信息,请参阅 GCC 信息,网址为 http://gcc.gnu.org/onlinedocs/。

在每个使用或调用内联函数的翻译单元中,必须以完全相同的方式定义该函数。 此外,如果函数定义为 inline,但从未在同一转换单元中使用或调用,那么编译器将废弃该函数 (除非使用 -qkeepinlines 选项进行编译)。
foo called from main: return value = 3, address = 0x10000580
foo called from g: return value = 3, address = 0x10000580重新定义具有相同名称但具有不同函数体的内联函数是非法的; 但是,编译器不会将此标记为错误,而只是为在编译命令行上输入的第一个文件中定义的版本生成函数体,并废弃其他函数体。 因此,以下示例 (在两个不同文件中以不同方式定义了内联函数 foo ) 可能不会生成预期结果:// a.C
#include <stdio.h>
inline int foo(){
return 6;
}
void g() {
printf("foo called from g: return value = %d, address = %p\n", foo(), &foo);
}
// b.C
#include <stdio.h>
inline int foo(){
return 3;
}
void g();
int main() {
printf("foo called from main: return value = %d, address = %p\n", foo(), &foo);
g();
}
使用命令 xlc++ a.C
b.C 编译时,输出为:foo called from main: return value = 6, address = 0x10001640
foo called from g: return value = 6, address = 0x10001640从 main 调用 foo 不会使用 b.C中提供的内联定义,而是将调用 foo 作为 a.C中定义的常规外部函数。 您负责确保具有相同名称的内联函数定义在转换单元之间完全匹配,以避免意外结果。// a.C
#include <stdio.h>
inline int foo(){
static int x = 23;
printf("address of x = %p\n", &x);
x++;
return x;
}
void g() {
printf("foo called from g: return value = %d\n", foo());
}
// b.C
#include <stdio.h>
inline int foo()
{
static int x=23;
printf("address of x = %p\n", &x);
x++;
return x;
}
void g();
int main() {
printf("foo called from main: return value = %d\n", foo());
g();
}
此程序的输出显示 foo 的两个定义中的 x 确实是同一对象:address of x = 0x10011d5c
foo called from main: return value = 24
address of x = 0x10011d5c
foo called from g: return value = 25 如果要确保定义为内联的函数的每个实例都被视为单独的函数,那么可以在每个转换单元的函数定义中使用 static 说明符,或者使用 -qstaticinline 选项进行编译。 但是请注意,静态内联函数在模板实例化期间从名称查找中移除,因此无法找到。 