C语言中头文件中的 static inline 函数以及 __attribute__((always_inline)) 强制内联展开

头文件中的 static inline函数

主要学习参考如下,且本文基于C语言,C++中static有不同作用:
https://blog.csdn.net/huanghui167/article/details/41346663
https://www.runoob.com/w3cnote/cpp-inline-usage.html


首先明确,inline只是建议内联,并不会强制内联,即使gcc已经开到了O3的优化等级,也可能不会内联。

在Linux系统下使用objdump命令可以看可执行文件的反汇编文件看具体有无内联。如果没有内联成功的话应该可以看到函数调用过程。


我主要以使用inline函数为目的,inline函数的定义一般放在头文件中,其他源文件要用的时候,直接把定义了inline函数的头文件include进来即可。如果在源文件中定义,在头文件中声明,则会变成为非内联函数的调用,因为每个源文件都是独立编译的,编译完之后只能按照普通函数一样调用

然后就是为什么在头文件中使用inline建议加入static?

1、由上可知,inline函数仅仅只是建议内联,有可能不会内联,所以当inline函数没有内联时,它只作为普通函数调用;
2、其次inline函数多用在头文件中,所以最终等于一个普通函数在头文件中定义,如果又被多个源文件包含,那么就会出现重定义的情况
3、就C语言而言,建议在头文件中定义的函数都要加上static,我已尝试,如果不加,又被多个源文件包含,编译不会通过。


强制内联展开

在ARM系统下,可以给函数增加__attribute__((always_inline))属性让inline函数可以强制展开,但是仅限于ARM,因为attribute是GNU C特色之一。所以其实不太了解win系统下怎么使用强制内联展开。

则,对于ARM Linux,可以将static inline函数定义变成以下形式:

static inline __attribute__((always_inline)) void f()

注(部分引自菜鸟教程):

慎用 inline
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?如果所有的函数都是内联函数,还用得着"内联"这个关键字吗?
内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率
如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。

经查阅反汇编代码后发现,可能会出现以下问题:

1、汇编代码中出现长跳转(因为代码过长),较短跳转更耗时;
2、寄存器不够,因为所有代码都在一个文件中,原本在函数中可以在栈内解决的变量需要额外寄存器。

以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

总结
内联函数并不是一个增强性能的灵丹妙药。只有当函数非常短小的时候它才能得到我们想要的效果;但是,如果函数并不是很短而且在很多地方都被调用的话,那么将会使得可执行体的体积增大。
最令人烦恼的还是当编译器拒绝内联的时候。在老的实现中,结果很不尽人意,虽然在新的实现中有很大的改善,但是仍然还是不那么完善的。一些编译器能够足够的聪明来指出哪些函数可以内联哪些不能,但是大多数编译器就不那么聪明了,因此这就需要我们的经验来判断。如果内联函数不能增强性能,就避免使用它!

你可能感兴趣的:(C语言中头文件中的 static inline 函数以及 __attribute__((always_inline)) 强制内联展开)