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

8
我已经阅读了许多关于在头文件中定义函数时使用 static inlineinline 的帖子,这些函数需要跨多个翻译单元进行访问。由于具有外部链接,似乎 inline 是正确的选择。
我的问题是,在 .h 文件中使用 inline 限定符定义函数会导致代码大小的增加:
  • 使用 inline 生成的代码扩展是否仍然比使用 static inline 生成的代码扩展更小?

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


如果您担心您的内联函数可能无法内联,那么也许您一开始就不应该内联它们?如果您没有担心,那么编译器将自动内联代码,代码扩展(假如它确实能给您带来速度上的好处;如果没有的话,则一开始内联该函数是毫无意义的)应该是可以接受的。不要随意使用 inline。谨慎并审慎地使用它,如果有疑问,请不要使用。另请参阅C99 中未使用 staticexterninline 是否有用? - Jonathan Leffler
我在代码中使用inline的原因主要是为了允许在头文件中定义函数。如果没有使用inline / static inline,编译器就会抱怨有多个符号定义。尽管我有点担心代码大小,但我主要想看看哪种方法能给我更多的好处,即少一些代码扩展- inline还是static inline。 - thegeeklife
@thegeeklife:在某些.c文件中,纯粹的inline(以及extern inline)将是这两个选项中更好的选择。这意味着您正在创建单个逻辑函数,而不是许多函数,正如我在答案中所概述的那样。但是,您应该考虑是否真的需要头文件中的代码。将代码放在.c文件中更简单,而且您不会冒着强制编译器内联其他可能没有的风险(正如Jonathan指出的那样)。您可以将extern inline放置的.c文件也可能是放置定义的逻辑位置。 - Ulfalizer
还要注意,如果您使用链接时优化,编译器可以在不使用inline的情况下内联调用来自不同翻译单元(.c文件)的函数。 - Ulfalizer
1个回答

6
这段内容讲述了使用关键字inlinestatic inline在函数声明中的不同作用。相比于static inlineinline关键字的使用可以生成更小的代码,因为它给函数提供了外部链接性,这样来自不同翻译单元的函数调用将引用同一个逻辑函数。而使用static inline则会为每个翻译单元生成一个唯一的函数实例,如果编译器选择不进行内联,则可能会增加代码大小(同时重复定义函数也是不好的)。
需要使用extern关键字是因为它使编译器生成可从其他翻译单元调用的函数的外部定义。如果没有extern,则不会生成这样的实例。没有extern的情况与内部链接性不同,因为inline定义仅提供对函数外部定义的"替代"。仍然必须存在外部定义(即,某些转换函数必须使用extern生成外部定义),并且编译器可以自由地选择是否使用它。
以上所述为C11标准中相关规定的概括(ISO/IEC 9899:2011 §6.7.4 Function specifiers, ¶7)。
另外,我认为使用inline不值得一提(作为提示-编译器仍然可以选择不内联),相比于让编译器自行决定何时进行内联。对于支持链接时优化的现代编译器,如果传递正确的标志(例如,在GCC中使用-flto),编译器甚至可以跨翻译单元内联函数。

非常出色的回答,但是当你写inline时,你(通常)仍然让编译器选择是否对函数进行内联。 - Dietrich Epp
@DietrichEpp:我的意思是想表达那个,但也许我没有表达清楚。我会再看一遍,看看能否澄清。 - Ulfalizer
我可能只是在阅读底部段落时写下了那句话。 - Dietrich Epp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接