内联函数
内联函数(inline)是 C99 引入的特性,建议编译器将函数调用替换为函数体,消除调用开销。内联适合频繁调用的小函数,但过度使用会增加代码体积。理解内联的语义和限制,是优化性能的关键。
基本用法
inline int max(int a, int b)
{
return (a > b) ? a : b;
}
/* 使用 */
int m = max(3, 5); /* 编译器可能内联展开 */
与宏对比
/* 宏:无类型检查,可能有副作用 */
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/* 内联函数:有类型检查,无副作用 */
inline int max(int a, int b)
{
return (a > b) ? a : b;
}
int x = 5;
int m1 = MAX(x++, 3); /* x 可能自增两次 */
int m2 = max(x++, 3); /* x 只自增一次 */
C99 内联语义
C99 内联语义较复杂:
/* 头文件 */
inline int add(int a, int b)
{
return a + b;
}
/* 需要外部定义 */
extern inline int add(int a, int b);
或:
/* 头文件 */
static inline int add(int a, int b)
{
return a + b;
}
static inline 是最常用的方式,每个编译单元有自己的副本。
何时使用内联
适合内联:
- 函数体很小(1-3 行)
- 频繁调用
- 在头文件中定义
不适合内联:
- 函数体很大
- 递归函数
- 调用次数少
- 包含复杂控制流
编译器提示
/* GCC:总是内联 */
__attribute__((always_inline)) inline int add(int a, int b)
{
return a + b;
}
/* GCC:不内联 */
__attribute__((noinline)) int complex_func(void);
常见错误
内联大函数:
inline void process_file(const char *filename)
{
/* 100 行代码 */
/* 内联会导致代码膨胀 */
}
递归内联:
inline int factorial(int n)
{
if (n <= 1) return 1;
return n * factorial(n - 1); /* 编译器不会内联递归 */
}
最佳实践
- 小函数(1-3 行)用
static inline - 头文件中定义内联函数
- 不假设一定内联(编译器决定)
- 用
inline替代简单宏 - 关注代码大小和缓存影响