在编译器命令中添加“-O”选项。仅当启用优化时才启用内联。
C99 内联函数
默认情况下,Clang 在 GNU C11 模式下构建 C 代码,因此它对 inline 关键字使用标准 C99 语义。这些语义不同于 GNU C89 模式中的语义,后者是 5.0 之前的 GCC 版本中的默认模式。例如,考虑以下代码:
inline int add(int i, int j) { return i + j; }
int main() {
int i = add(4, 5);
return i;
}
在 C99 中,内联意味着一个函数的定义仅用于内联,并且在程序的其他地方还有另一个定义(没有内联)。这意味着这个程序是不完整的,因为如果 add 没有内联(例如,在没有优化的情况下编译时),那么 main 将有一个未解析的对另一个定义的引用。因此,我们将得到一个(正确的)链接时错误,如下所示:
Undefined symbols:
"_add", referenced from:
_main in cc-y1jXIr.o
相比之下,GNU C89 模式(在旧版本的 GCC 中默认使用)是 C89 标准加上许多扩展。C89 没有 inline 关键字,但 GCC 将其识别为扩展,并将其视为对优化器的提示。
有几种方法可以解决这个问题:
- 更改添加到静态内联函数。如果只有一个翻译单元需要使用该功能,这通常是正确的解决方案。静态内联函数总是在翻译单元中解析,因此您不必在程序的其他地方添加函数的非内联定义。
- 从此 add 的定义中删除 inline 关键字。内联函数不需要 inline 关键字,也不保证一定会这样。一些编译器完全忽略它。Clang 将其视为程序员的温和建议。
- 在程序的其他地方提供 add 的外部(非内联)定义。这两个定义必须是等价的!
- 通过将 -std=gnu89 添加到 Clang 选项集以编译 GNU C89 方言。仅当程序源无法更改或程序还依赖于无法更改的其他 C89 特定行为时,才建议使用此选项。
所有这些仅适用于 C 代码;C++ 中 inline 的含义与其在 GNU89 或 C99 中的含义大不相同。