在C99中,没有“静态”或“外部”的“内联”有用吗?

在C99中,没有“静态”或“外部”的“内联”有用吗?

当我试图构建这个代码

inline void f() {}int main(){
    f();}

使用命令行

gcc -std=c99 -o a a.c

我得到一个链接器错误(未定义的引用f)。如果我使用static inlineextern inline而不是仅仅inline,或者如果我用-O(因此函数实际上是内联的)。

“C99标准”第6.7.4(6)段似乎界定了这种行为:

如果翻译单元中的函数的所有文件范围声明都包括inline无函数说明符extern,则该翻译单元中的定义是内联定义。内联定义不提供函数的外部定义,也不禁止在另一个翻译单元中进行外部定义。内联定义提供了外部定义的替代方案,译者可以使用该定义来实现对同一翻译单元中的函数的任何调用。未指定对函数的调用是使用内联定义还是使用外部定义。

如果我正确地理解了所有这些,那么定义了一个具有函数的编译单元。inline正如上面的示例所示,只有当有一个具有相同名称的外部函数时,才会进行一致的编译,而且我永远也不知道是调用了我自己的函数还是调用了外部函数。

这种行为不是完全愚蠢吗?定义函数有用吗?inlinestaticextern在C99?我是不是遗漏了什么?

答案摘要

当然,我漏掉了什么,而且我的行为也不愚蠢。*)

尼莫解释,想法是把定义职能

inline void f() {}

在头文件中,并且只有声明

extern inline void f();

在相应的.c文件中。只有extern声明触发外部可见二进制代码的生成。确实没有用inline在.C文件中-它只在头文件中有用。

就像乔纳森答覆中引述的C99委员会的理据说明,inline都是关于编译器优化,这些优化要求函数的定义在调用的站点上可见。这只能通过将定义放在标头中才能实现,当然,头中的定义不能在编译器每次看到它时发出代码。但是,由于编译器并不强制实际内联一个函数,所以外部定义必须存在于某个地方。


潇潇雨雨
浏览 384回答 3
3回答

拉风的咖菲猫

内联定义提供了替代外部定义,哪一位翻译可以,可能用于实现对同一翻译单元中的函数的任何调用。所以,如果你知道函数的行为f如果你想在一个紧密的循环中调用它,你可以复制-粘贴它的定义到一个模块中,以防止函数调用;或,您可以提供一个定义,就当前模块而言,它是等效的(但跳过输入验证或任何您可以想象的优化)。然而,编译器编写者可以选择对程序大小进行优化。
打开App,查看更多内容
随时随地看视频慕课网APP