C语言inline的用法

inline这个关键词,是从C99开始出现的。它要解决的问题很明确,对于那些短小精干频繁调用的函数,如果是inline的,编译的时候,函数调用位置会被替换成函数的代码块,省掉了函数调用的压栈出栈等操作,可以加快程序的执行速度,代价只是增加了一点点程序文件的体积。本文以gcc的inline行为为准。

1, static inline

这是最纯粹的inline用法,我们始终要记住,C语言的编译是按文件进行的,每个.c文件单独编译,最后链接在一起。既然是单独编译,要发挥inline的作用,定义为inline的函数,必然要与调用者在同一个文件中。static inline的语义,就是先static,此函数只在当前文件可见,然后inline,在调用处展开。

另外,inline要出现在函数定义(definition)的地方,出现在申明(declaration)的地方没有意义!如果一个函数是static inline,就直接定义了,没有必要再申明,在申明的位置出现inline反而可能会有编译错误。

inline对于编译器而言,只是个建议,不是强制,如下两种情况,编译器会忽略掉inline:

(1)函数的地址被使用的时候。如通过函数指针对函数进行了间接调用。这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址。

(2)其他一些无法展开的情况,比如函数本身有递归调用自身的行为等。

其实,对于以上两种情况,程序员就不应该使用inline。

2, inline

对于gcc而言,仅有inline的函数(无static),在当前文件内部,其表现与static inline一样,在调用处展开,而对于外部文件的调用(没有static修饰,就是extern函数),跟普通全局函数一样。

因此,gcc实际上在只有inline的时候,一定会为函数生成一份独立的汇编码,以便被别的模块调用。在别的文件中,这个函数跟其它全局函数没有区别。

3, extern inline

这是不建议使用的定义方式,gcc一定不会为这样定义的函数生成独立的汇编码。

4, inline与gcc -On优化参数

inline关键字仅仅是建议编译器做内联展开处理,而不是强制。在gcc编译器中,如果编译优化设置为-O0,即使是inline函数也不会被内联展开,除非设置了强制内联(__attribute__((always_inline)))属性。

如果使用 -O0,函数定义为 inline,会有链接错误。 -O0表示inline函数不展开,还是调用,inline表示对当前文件的调用不生成独立的汇编码,因此在链接的时候,会有找不到inline函数的错误。

最后,我个人的一点感觉(不确定):使用-O3的时候,static的函数,gcc也可能自动为其加上inline属性。

你可能感兴趣的