C语言 代码大小:头文件中定义的函数的静态内联与内联



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

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

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

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

它可以生成更小的代码。原因是inline(与static inline相反)将为函数提供外部链接,以便来自不同翻译单元的所有函数调用都引用相同的逻辑函数。使用static inline,每个翻译单元将获得函数的唯一实例,如果编译器选择不内联,这可能会增加代码大小。(在代码方面,没有多个相同的函数也更干净。

您需要在某处extern的原因是,它使编译器生成可以从其他翻译单元调用的函数的外部定义。如果没有extern,就不会生成这样的实例。无extern情况与内部联系的不同之处在于,inline定义仅提供了函数外部定义的"替代方案"。外部定义必须仍然存在(即,某些翻译函数必须使用 extern 来生成外部定义),并且编译器可以自由使用它而不是它想要使用它。

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

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

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

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

最新更新