7

我已经阅读了很多关于在头文件static inlineinline定义函数以跨多个翻译单元访问的文章。inline由于具有外部联系,这似乎是正确的方法。

inline我的问题是关于在 .h 文件中定义函数时使用说明符导致的代码大小:

  • 由 产生的代码扩展是否inline仍然小于由 引起的static inline

  • 为什么需要extern inline在相应的 .c 文件中声明?

4

1 回答 1

5

它可以生成更小的代码。原因是inline(相对于static inline)将给函数外部链接,以便从不同翻译单元对函数的所有调用都引用相同的逻辑函数。使用static inline,每个翻译单元将获得该函数的唯一实例,如果编译器选择不内联,这可能会增加代码大小。(没有多个相同的功能也更简洁。)

您需要extern某处的原因是因为它使编译器生成可以从其他翻译单元调用的函数的外部定义。没有extern,就不会生成这样的实例。nocaseextern与内部链接的不同之处在于,该inline定义仅提供了函数外部定义的“替代方案”。外部定义必须仍然存在(即,必须使用某些翻译函数extern来生成外部定义),并且编译器可以随意使用它而不是它想要的。

这是一些相关的标准(对于 C11:ISO/IEC 9899:2011 §6.7.4 函数说明符,¶7):

任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,适用以下限制: 如果函数用inline函数说明符声明,则它也应在同一翻译单元中定义。如果翻译单元中函数的所有文件范围声明都包含inline没有 的函数说明符extern,则该翻译单元中的定义是内联定义. 内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中进行外部定义。内联定义提供了外部定义的替代方案,翻译器可以使用它来实现对同一翻译单元中函数的任何调用。未指定对函数的调用是使用内联定义还是外部定义。140)

140)由于内联定义不同于相应的外部定义以及其他翻译单元中的任何其他相应的内联定义,因此具有静态存储持续时间的所有相应对象在每个定义中也是不同的。

顺便说一句,inline与简单地让编译器自行选择何时内联相比,IMO 通常是不值得的(作为一个提示——编译器仍然可以不内联)。对于支持链接时优化-flto的现代编译器,如果您传递正确的标志(例如,在 GCC 中),编译器甚至可以跨翻译单元内联函数。

于 2015-03-11T23:16:41.333 回答