Effective-cpp-#30

Understand the ins and outs of inlining

inline函数,不是第一次接触这个概念了。编译器的最优化机制会被设计用来执行语境相关的最优化。但有利有弊,由于inline函数的主体会被插到调用处。这样一来,你的目标码会变得越来越大,有可能导致额外的paging行为。


通常来说,inline函数有两种定义方法——一是在类内定义函数,这是一种隐喻的方式;二是在定义式前加inline关键字。

注意

inline函数尽量置于头文件内,因为大多数build environment通常会在编译时进行inlining,这是因为为了将一个“函数调用”替换为“被调用函数的本体”,编译器必须知道那个函数长什么样子。

template的具体化与inline无关,我们需要的考虑的是——是否希望每一个具体实现的函数都是inline的,毕竟这有可能会引发代码膨胀。

关于编译器的问题,编译器不一定就真的会对inline函数进行inline行为,例如编译器通常不会对“通过函数指针而进行的函数调用”进行inline行为。另外,如果程序要调用某个inline函数,往往,编译器会生成一个outlined函数本体

最后一个需要注意的问题是,inline函数无法随着程序库的升级而升级。假设f是一个inline函数,而设计者修改了这个函数f,那么所有用到f的客户端程序都必须重新编译,而对于non-inline函数,客户端只需要重新链接即可,这比重新变异的负担少。

建议

  • 将大多数inline限制在小型的、被频繁调用的函数身上。这可以使得日后的调试和二进制升级更加容易,也可以使得潜在的代码膨胀问题最小化;
  • 不要只因为function template出现在头文件,就将它们声明为inline;