Q1:inline关键字
• 关于 inline 请求是否被接收
• inline 关键字是一项请求,如果这项请求被接收,编译器就必须认为它可以用一个表达式合理的将这个函数扩展开。
• 这种合理性体现在:这个内联函数的执行成本比一般的函数调用以及返回机制所带来的负荷低(编译器内部存在衡量方法)
• 处理一个 inline 函数有两个阶段
分析函数定义,以决定函数的“instrisic inline ability”(与编译器相关的内联能力,”instrisic”- 固有的,在此为“与编译器相关”)
注:如果一个函数因其复杂度或构建问题,被判定为不可成为 inline,则它会被转为一个 static 函数,并在“被编译模块”内产生对应的函数定义
真正的 inline 函数扩展操作在调用的那个点上进行展开
注:在 cfront 编译器中,若 inline 函数只有一个表达式,则其第二个或后继的调用操作将不被扩展
Q2:实际参数给内联函数带来的影响
• 均以以下内联函数为例:
inline int min(int i, int j)
{
return i < j ? i : j;
}
采用以下几种调用方式进行讨论:
int foo();
int bar();
int main()
{
int minval;
int val1 = 1024;
int val2 = 2048;
/*(1)*/ minval = min(foo(), bar() + 1);
/*(2)*/ minval = min(1024, 2048);
/*(1)*/ minval = min(val1, val2);
return 0;
}
• 实参为带副作用的表达式
解释:当实参为带副作用的表达式时,需要引入临时对象。如上述情况(1),此时需要导入一个临时对象,避免重复求值。转为下式:
int t1;
int t2;
minval = (t1 = foo()), (t2 = bar() + 1), t1 < t2 ? t1 : t2;
• 实参为常量表达式
解释:需要在替换前完成求值操作,后继的内联替换,可以直接将常量捆绑到对应位置。如上述情况(2),可以直接绑定常量。转为下式:
minval = 1024;
• 实参既不是副作用表达式也不是常量表达式
解释:此时直接进行替换即可