如果内联函数以结尾处的单个返回结尾,那么从概念上简单地用函数体替换调用者代码是微不足道的。
inline int foo(int i) {
return i - 1;
}
// prior to inline
int result = foo(k);
// => after inline
int result = k - 1;
如果有分支机构并且有多个回报,该怎么办?编译器如何生成正确的代码?简单的替换显然是不够的。
inline int foo(int i) {
if (i > 0)
return i - 1;
return i + 1;
}
// prior to inline
int result = foo(k);
// => after inline
int result;
if (k > 0)
result = k - 1;
result = k + 1;
答案 0 :(得分:1)
您可以看到inline temp编译器之后的输出。进行实验,您会看到它是如何完成的https://godbolt.org/z/0MkWLs
答案 1 :(得分:1)
允许编译器在编译期间进行各种形式的代码转换。对于您的示例,编译器可以将函数foo
转换为
int foo(int i)
{
int rv;
if (i > 0)
{
rv = i - 1;
goto end;
}
rv = i + 1;
end:
return rv;
}
然后可以将此代码插入到调用方中。在插入期间,编译器会引入变量来处理参数和内联函数的返回值。结果看起来像下面的代码。
int foo_rv;
int foo_param_i = k;
{
int i = foo_param_i;
if (i > 0)
{
rv = i - 1;
goto end:
}
rv = i + 1;
end:
foo_rv = rv
}
int result = foo_rv;
然后,编译器可以进一步优化此代码,得到下面的代码
{
if (k > 0)
{
result = k - 1;
goto end:
}
result = k + 1;
end:
}