C 语言内联函数(inline)的原理剖析以及应用场景
C 语言内联函数(inline)的原理剖析以及应用场景
内联函数和普通函数的区别:
普通函数:在f1()函数调用普通函数f0()时,将程序执行地址转变为f0的函数地址,执行完f0后,再将程序的执行地址转换为F1的函数地址。这种函数地址的转移操作需要保护现场和函数地址的压栈和出栈等操作,执行完成后恢复现场。
内联函数:在编译阶段,将f0的代码拷贝到f1的指定位置,在f1()函数调用普通函数f0()时,不需要函数地址的转移以及压栈出栈、保护现场等操作。
内联函数的优点和缺点:
优点:对于一些较小的函数,如果频繁调用,可以将其设计为内联函数,省去了执行函数地址转移等操作,占用系统资源更少,执行效率更高。
缺点:如果调用内联函数的地方太多,就会造成代码膨胀,因为编译器会把每个调用内联函数的位置都拷贝一份函数实现嵌入其中,重复的嵌入。
这点有点类似于结构体指针和结构体:结构体指针是一个指针,也就是结构体的地址,结构体变量是一段内存区域。在执行浅拷贝时,结构体指针拷贝的是8个字节的指针,结构体变量拷贝则拷贝整个内存区域。可能造成所占内存的增加,占用系统资源比指针多。
慎用内联
内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?
内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收
获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
以下情况不宜使用内联:
(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline 不应该出现在函数的声明中)。
上一篇: 带头节点的双向循环链表的实现
下一篇: 线程你真的了解它吗