4.3 函数内联
kf32clang会判断内联某个函数是否可以提升性能,当可以提升性能时会自动对该函数进行内联。这种自动内联通常不会显著增加代码体积,并且你可以使用编译器提示(hints)和选项来影响或控制函数是否被内联。
表4.3 函数内联
| 内联选项,关键字,或者属性 | 描述 |
|---|---|
__inline__ | 在函数定义或声明中使用该关键字,可作为提示(hint),告诉编译器优先考虑将该函数内联。然而,对于每次函数调用,编译器仍然会自行决定是否真正进行内联。 |
__attribute__((always_inline)) | 在函数定义或声明中使用此函数属性,可告诉编译器总是内联该函数,但存在某些例外情况,例如递归函数可能无法内联。该属性会覆盖 -fno-inline-functions 选项的设置。 |
__attribute__((noinline)) | 在函数定义或声明中使用此函数属性,可告诉编译器不要内联该函数。该属性等效于__declspec(noinline)。 |
-fno-inline-functions | 这是一个编译器命令行选项。在编译时指定该选项,可以禁止函数内联。该选项会覆盖 __inline__ 提示。 |
4.3.1 函数内联示例
此示例展示了__attribute__((always_inline))和-fno-inline-functions在C99模式下的效果(C文件的默认行为)。将以下代码复制到 file.c。
int bar(int a)
{
a = a * (a + 1);
return a;
}
__attribute__((always_inline)) static int row(int a)
{
a = a * (a + 1);
return a;
}
int foo(int i)
{
i = bar(i);
i = i - 2;
i = bar(i);
i++;
i = row(i);
i++;
return i;
}
在示例代码中,函数 bar 和 row 是相同的,但函数 row 总是被内联。使用以下编译器命令,在 -O2 优化级别下分别编译:第一条命令使用 -fno-inline-functions,第二条命令不使用。
kf32clang --target=kf32r -march=kf32r -S file.c -O2 -o file_no_inline.s -fno-inline-functions
kf32clang --target=kf32r -march=kf32r -S file.c -O2 -o file_inline.s
生成的代码如下所示:
使用 -fno-inline-functions 的编译结果 | 不使用 -fno-inline-functions 的编译结果 |
|---|---|
| |
使用 -fno-inline-functions 编译时,编译器不会内联函数 bar。不使用 -fno-inline-functions 编译时,编译器会内联函数 bar。编译器总是内联函数 row,即使它与函数 bar内容相同。