C 代码大小:头文件中定义的函数的静态内联与内联
我读过不少关于在头文件中定义函数以跨多个翻译单元访问时使用C 代码大小:头文件中定义的函数的静态内联与内联,c,static,inline,code-size,C,Static,Inline,Code Size,我读过不少关于在头文件中定义函数以跨多个翻译单元访问时使用静态内联和内联的文章。由于有外部链接,inline似乎是正确的选择 我的问题是关于在.h文件中定义函数时使用inline说明符所产生的代码大小: 由内联生成的代码扩展是否仍然小于由静态内联生成的代码扩展 为什么在相应的.c文件中需要extern inline声明 它可以生成更小的代码。原因是内联(与静态内联)将为函数提供外部链接,以便来自不同翻译单元的所有函数调用都引用相同的逻辑函数。使用静态内联,每个翻译单元将获得函数的唯一实例,如果
静态内联
和内联
的文章。由于有外部链接,inline
似乎是正确的选择
我的问题是关于在.h文件中定义函数时使用inline
说明符所产生的代码大小:
- 由
生成的代码扩展是否仍然小于由内联
生成的代码扩展静态内联
- 为什么在相应的.c文件中需要
声明extern inline
- 它可以生成更小的代码。原因是
内联
(与静态内联
)将为函数提供外部链接,以便来自不同翻译单元的所有函数调用都引用相同的逻辑函数。使用静态内联,每个翻译单元将获得函数的唯一实例,如果编译器选择不内联,这可能会增加代码大小。(不具有多个相同的函数也是更简洁的代码方式。)
您需要extern
的原因是它使编译器生成可以从其他翻译单元调用的函数的外部定义。如果没有extern
,则不会生成此类实例。no-extern
案例与内部链接的不同之处在于inline
定义仅提供函数外部定义的“替代”。外部定义必须仍然存在(即,某些翻译函数必须使用extern
来生成外部定义),并且编译器可以自由使用它,而不是它想要的
以下是一些相关标准(对于C11:ISO/IEC 9899:2011§6.7.4功能规范,^7):
任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,以下限制适用:如果函数是用内联
函数说明符声明的,则它也应在同一翻译单元中定义。如果翻译单元中某个函数的所有文件范围声明都包含inline
函数说明符,而不包含extern
,则该翻译单元中的定义为内联定义。内联定义不为函数提供外部定义,也不禁止在其他翻译单元中使用外部定义。内联定义提供了外部定义的替代方法,转换器可以使用外部定义在同一翻译单元中实现对函数的任何调用。未指定对函数的调用是使用内联定义还是外部定义。140)
140)因为内联定义不同于相应的外部定义和任何其他定义
其他翻译单元中对应的内联定义,所有对应的对象都具有静态存储
在每个定义中,持续时间也是不同的
顺便说一句,
inline
IMO通常不值得(作为提示——编译器仍然可以自由地不内联),而只是让编译器自己选择何时内联。对于支持链接时间优化的现代编译器,如果您在GCC中传递正确的标志(例如,-flto
),编译器甚至可以跨翻译单元内联函数。回答得很好,但当您编写内联
时,您(通常)仍然让编译器选择是否内联函数。@DietrichEpp:我本想表达出来,但可能失败了。我会检查一下,看看是否可以澄清。我写这篇文章的时候可能刚刚读了最后一段。如果你担心你的内联函数可能没有内联,也许你不应该首先内联它们?如果您不担心,那么编译器无论如何都会内联代码,并且代码扩展(这可能会给您带来速度上的好处;如果没有,那么一开始就没有内联函数的任何意义)应该是可以接受的。不要随意使用inline
。使用时要谨慎和有判断力,如果有疑问,不要使用。另请参见在我的代码中使用内联的原因基本上是为了允许在头文件中定义函数。如果没有内联/静态内联,编译器会抱怨多个符号定义。我有点担心代码的大小,但我主要是想看看哪种方式能给我带来更多的好处,即减少代码扩展-内联或静态行。@thegeeklife:Plaininline
(以及一些.c
文件中的extern inline
)这将意味着这两个选项的更好。这意味着你正在创建一个单一的逻辑函数,而不是很多,如我的答案中所概述的。你应该考虑你是否真的需要在头文件中使用代码。在代码< >代码>文件>中,代码更简单,而且你不会冒险将编译器推到内联的东西中,否则它就不会有。(正如Jonathan所指出的,这似乎是您所担心的)。将外部内联的.c
文件可能是放置定义的合乎逻辑的地方。还要注意,编译器可以内联来自不同翻译单元的函数调用(.c
文件)如果使用链接时间优化,则无需使用内联
。