在C99中,没有“静态”或“外部”的“内联”有用吗?
当我试图构建这个代码
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)段似乎界定了这种行为:
如果翻译单元中的函数的所有文件范围声明都包括inline
无函数说明符extern
,则该翻译单元中的定义是内联定义。内联定义不提供函数的外部定义,也不禁止在另一个翻译单元中进行外部定义。内联定义提供了外部定义的替代方案,译者可以使用该定义来实现对同一翻译单元中的函数的任何调用。未指定对函数的调用是使用内联定义还是使用外部定义。
如果我正确地理解了所有这些,那么定义了一个具有函数的编译单元。inline
正如上面的示例所示,只有当有一个具有相同名称的外部函数时,才会进行一致的编译,而且我永远也不知道是调用了我自己的函数还是调用了外部函数。
这种行为不是完全愚蠢吗?定义函数有用吗?inline
无static
或extern
在C99?我是不是遗漏了什么?
答案摘要
当然,我漏掉了什么,而且我的行为也不愚蠢。*)
如尼莫解释,想法是把定义职能
inline void f() {}
在头文件中,并且只有声明
extern inline void f();
在相应的.c文件中。只有extern
声明触发外部可见二进制代码的生成。确实没有用inline
在.C文件中-它只在头文件中有用。
就像乔纳森答覆中引述的C99委员会的理据说明,inline
都是关于编译器优化,这些优化要求函数的定义在调用的站点上可见。这只能通过将定义放在标头中才能实现,当然,头中的定义不能在编译器每次看到它时发出代码。但是,由于编译器并不强制实际内联一个函数,所以外部定义必须存在于某个地方。