inline function specifier
声明一个 inline function 。
目录 |
语法
| inline 函数声明 | (C99起) | ||||||||
说明
inline
说明符的意图是作为编译器的优化提示,例如执行
函数内联
时,通常要求函数定义在调用点可见。出于优化目的,编译器可以(且通常确实会)忽略
inline
说明符的存在与否。
如果编译器执行函数内联,它会将该函数的调用替换为其函数体,从而避免函数调用的开销(将数据压入堆栈和检索结果),这可能导致可执行文件变大,因为函数的代码必须多次重复。其结果类似于 函数式宏 ,不同之处在于函数中使用的标识符和宏引用的是定义点可见的定义,而非调用点可见的定义。
无论是否发生内联,以下内联函数的语义都得到保证:
任何具有内部链接的函数都可以被声明为
static inline
,且没有其他限制。
非静态内联函数不能定义非常量的函数局部静态变量,也不能引用文件作用域的静态变量。
static int x; inline void f(void) { static int n = 1; // 错误:非静态内联函数中存在非常量静态变量 int k = x; // 错误:非静态内联函数访问了静态变量 }
如果非静态函数被声明为
inline
,则必须在同一翻译单元内定义。不使用
extern
的内联定义不具有外部可见性,且不会阻止其他翻译单元定义同一函数。这使得
inline
关键字成为在头文件内定义函数的
static
替代方案,这些头文件可能被包含在同一个程序的多个翻译单元中。
如果函数在某个翻译单元中被声明为
inline
,它并不需要在所有地方都被声明为
inline
:最多只能有一个翻译单元同时提供一个常规的非内联非静态函数,或声明为
extern inline
的函数。这个翻译单元被称为提供
外部定义
。为避免未定义行为,若具有外部链接的函数名称在表达式中被使用,程序中必须存在一个外部定义,详见
单一定义规则
。
具有外部链接的内联函数的地址始终是外部定义的地址,但当使用该地址进行函数调用时,调用的是 内联定义 (若存在于翻译单元中)还是 外部定义 是未指定的。在内联定义中定义的静态对象与在外部定义中定义的静态对象是不同的:
inline const char *saddr(void) // 本文件中使用的内联定义 { static const char name[] = "saddr"; return name; } int compare_name(void) { return saddr() == saddr(); // 未指定行为,其中一个调用可能来自外部 } extern const char *saddr(void); // 同时也会生成外部定义
C程序不应依赖于调用的是函数的内联版本还是外部版本,否则行为是未定义的。
关键词
注释
inline
关键字源自 C++,但在 C++ 中,若函数被声明为
inline
,则必须在每个翻译单元中都声明为
inline
,且每个内联函数的定义必须完全相同(在 C 语言中,定义可以不同,根据差异仅导致未指定的行为)。另一方面,C++ 允许非常量函数局部静态变量,且来自内联函数不同定义的所有函数局部静态变量在 C++ 中相同,但在 C 语言中却彼此独立。
示例
头文件 "test.h"
#ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED inline int sum(int a, int b) { return a + b; } #endif
源文件 "sum.c"
#include "test.h" extern inline int sum(int a, int b); // 提供外部定义
源文件 "test1.c"
#include <stdio.h> #include "test.h" extern int f(void); int main(void) { printf("%d\n", sum(1, 2) + f()); }
源文件 "test2.c"
#include "test.h" int f(void) { return sum(3, 4); }
输出
10
参考文献
- C23 标准 (ISO/IEC 9899:2024):
-
- 6.7.4 函数说明符 (p: 待定)
- C17 标准 (ISO/IEC 9899:2018):
-
- 6.7.4 函数说明符 (p: TBD)
- C11 标准 (ISO/IEC 9899:2011):
-
- 6.7.4 函数说明符 (p: 125-127)
- C99标准(ISO/IEC 9899:1999):
-
- 6.7.4 函数说明符(第112-113页)
参见
|
C++ 文档
关于
inline
说明符
|