我已经阅读了很多关于使用static inline
和inline
的文章,同时在头文件中定义函数以跨多个翻译单元进行访问。由于具有外部联系,似乎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
函数说明符声明函数,则还应在同一翻译单元中定义该函数。如果翻译单元中函数的所有文件范围声明都包含不带extern
的inline
函数说明符,则该转换单元中的定义是内联定义。内联定义不为函数提供外部定义,也不禁止在另一个翻译单元中使用外部定义。内联定义提供了外部定义的替代方法,翻译人员可以使用它来实现对同一翻译单元中函数的任何调用。未指定对函数的调用是使用内联定义还是外部定义。140)140) 由于内联定义不同于相应的外部定义和任何其他定义 其他翻译单元中的相应内联定义,所有具有静态存储的相应对象 持续时间在每个定义中也是不同的。
顺便说一下,与简单地让编译器纯粹自己选择何时内联相比,inline
IMO 通常不值得(作为提示 - 编译器仍然可以自由地不内联)。对于支持链接时优化的现代编译器,如果您传递正确的标志(例如,GCC 中的 -flto
),编译器甚至可以跨翻译单元内联函数。