1.内联inline是一个请求,编译器一般会评估函数是否值得内联或者能够内联,如果满足内联条件则编译器会对函数进行内联处理。
2.处理一个内联函数一般有两个阶段:
(1)分析函数定义以决定函数的本质的内联能力(intrinsic inline ablitity)
函数如果因为其复杂度或构建原因被判断为不可inline则会被转换为一个static函数,并在被编译模块内产生对应的函数定义。另外理想的链接器会把下文提到的由调用产生的重复的东西清理调,但是事实上并没有这么做(编译器可能会可能不会)。UNIX环境中的strip命令可以达到这个目的。
(2)真正的inline函数扩展操作是在调用的那一点上。这会带来参数的求值操作和临时性对象的管理。
3.形式参数的处理:
编译器一般会用实际参数来取代内联函数的形式参数。如果实际参数是一个常量表达式则先求值再替换。但是实际参数可能会是带有副作用的表达式,他可能会导致实际参数被多次求值。所以编译器就会产生一个临时对象来避免这种现象。
inline int min(int i,int j) {return i<j?i:j;} inline int bar { int minval,val1=1024,val2=2048; minval=min(val1,val2); //1 minval =min(1024,2048); //2 minval= min(foo(),bar()+1); //3 //第一种参数直接代换 minval =val1<val2?val1:val2; //1 //第二种代换后直接代换成常量 minval=1024; //第三章引入临时变量 int ti,t2; minval=(t1=foo()),(t2=bar()+1),t1<t2?t1:t2;
上面的代码中第三种情况如果不产生临时变量则foo将会被计算3次。另外第三种情况运用了逗号运算符,依次计算逗号两边从左到右的表达式的值,最后返回最后一个表达式的值(有资料说可能要整体加大括号,视编译器而定)
https://blog.csdn.net/tkp2014/article/details/48915491
4.局部变量的处理
inline函数内的局部变量必须被放在函数调用的一个封闭区段中。如果inline函数以单一表达式扩展多次,则每次扩展都需要自己的一组局部变量。如果inline函数以分离的多个式子被扩展多次,则只需要一组局部数据,可以重复利用(因为被放在一个封闭区段中有自己的作用范围)
总结:inline函数是一个复杂的过程,简单的函数可能不能inline,inline内部再inline也能导致不能inline。另外过多的inline会产生大量扩展码,使程序大小膨胀。