我已经阅读了很多关于使用static inline
和inline
同时定义头文件中的函数以便跨多个翻译单元进行访问的帖子。由于有外部联系,似乎inline
是正确的方法。
我的问题是在定义.h文件中的函数时使用inline
说明符导致的结果代码大小:
inline
生成的代码扩展是否仍然低于static inline
引起的代码扩展?
为什么在相应的.c文件中需要extern inline
声明?
答案 0 :(得分:5)
它可以生成更小的代码。原因是inline
(与static inline
相对)将赋予函数外部链接,以便来自不同转换单元的对函数的所有调用都引用相同的逻辑函数。使用static inline
,每个翻译单元将获得该函数的唯一实例,如果编译器选择不内联,则可能会增加代码大小。 (代码也更清晰,没有多个相同的功能。)
你需要extern
的原因是因为它使编译器生成可以从其他翻译单元调用的函数的外部定义。如果没有extern
,则不会生成此类实例。 no - extern
情况与内部链接的不同之处在于inline
定义仅提供函数外部定义的“替代”。外部定义必须仍然存在(即,某些翻译函数必须使用extern
来生成外部定义),并且编译器可以自由地使用它而不是它想要的。
这里有一些相关的标准(对于C11:ISO / IEC 9899:2011§6.7.4函数说明符,¶7):
任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,以下限制适用:如果使用
inline
函数说明符声明函数,则它也应在同一转换单元中定义。如果翻译单元中函数的所有文件范围声明都包含inline
函数说明符而没有extern
,那么该翻译单元中的定义是内联定义。内联定义不提供函数的外部定义,也不禁止另一个转换单元中的外部定义。内联定义提供了外部定义的替代,翻译器可以使用该定义在同一翻译单元中实现对该功能的任何调用。未指定对函数的调用是使用内联定义还是使用外部定义。 140)140)由于内联定义与相应的外部定义和任何其他定义不同 其他翻译单元中的相应内联定义,所有具有静态存储的对应对象 持续时间在每个定义中也是不同的。
顺便说一句,inline
IMO通常不值得(作为一个提示 - 编译器仍可以自由不内联),而不是简单地让编译器选择何时纯粹内联。对于支持链接时优化的现代编译器,如果传递正确的标志(例如,GCC中的-flto
),编译器甚至可以跨翻译单元内联函数。