最佳答案
当我尝试构建这个代码时
inline void f() {}
int main()
{
f();
}
使用命令行
gcc -std=c99 -o a a.c
我得到一个链接器错误(对 f
的未定义引用)。如果使用 static inline
或 extern inline
而不仅仅是 inline
,或者使用 -O
编译(因此函数实际上是内联的) ,则错误消失。
这种行为似乎在 C99标准的第6.7.4(6)段中得到了定义:
如果一个翻译单元中的函数的所有文件范围声明都包含没有
extern
的inline
函数说明符,那么该翻译单元中的定义就是一个内联定义。内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中使用外部定义。内联定义提供了外部定义的替代方案,翻译人员可以使用外部定义实现对同一翻译单元中的函数的任何调用。未指定对函数的调用是使用内联定义还是使用外部定义。
如果我的理解正确的话,一个编译单元的函数定义为 inline
,就像上面的例子一样,只有当一个外部函数的名字相同的时候,编译单元才能一致地进行编译,而且我从来不知道我自己的函数或者外部函数是否被调用。
这种行为不是很愚蠢吗?在 C99中定义一个没有 static
或 extern
的函数 inline
有用吗?我错过了什么吗?
当然,我遗漏了一些东西,这种行为并不愚蠢。 :)
作为 尼莫解释道,其思想是把函数的 定义
inline void f() {}
在头文件中,只有一个 声明
extern inline void f();
在相应的。文件。只有 extern
声明触发生成外部可见的二进制代码。而且 inline
在。C 文件——它只在头文件中有用。
正如 乔纳森在回答中引用了 C99委员会的理由解释的那样,inline
完全是关于编译器优化的,它要求函数的定义在调用的站点上可见。这只能通过将定义放在标头中来实现,当然,标头中的定义不能每次被编译器看到时都发出代码。但是,由于编译器不必实际内联函数,因此外部定义必须存在于某个地方。