gcc 在C语言中,什么是内联函数的非集成调用?

3mpgtkmj  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(146)

关于C中内联函数,GCC文档中提到:
当一个函数同时是内联的和静态的,如果所有对该函数的调用都被集成到调用者中,并且该函数的地址从未被使用过,那么该函数自己的汇编代码就从未被引用过。在这种情况下,GCC实际上并不输出该函数的汇编代码,除非您指定了选项-fkeep-inline-functions。如果有一个非集成调用,那么函数就像平常一样被编译成汇编代码。2如果程序引用了函数的地址,那么函数也必须像平常一样被编译,因为它不能被内联。
第一种情况很清楚:如果所有的调用都集成到调用程序中,那么就不需要生成汇编程序代码。
但是,什么是非集成呼叫
一个函数可能不适合内联,但是为什么一个函数调用会变得如此呢?

34gzjxbg

34gzjxbg1#

一个函数可能不适合内联,但是为什么一个函数调用会变得如此呢?
有几种可能性:

1.获取函数的地址

一般情况下,如果取一个函数的地址,例如建立一个调度表,那么编译器就不能优化 *“取地址+间接调用 *”回 “直接调用”.简单的例子:

static inline int inc (int i)
{
    return i + 1;
}

int (*pfunc)(int) = inc;

2.内联函数会使代码开销更大

编译器的成本模型并不完美,代码内联通常发生在编译的早期阶段,在GCC的情况下,这包括几百遍。这意味着成本计算可能远远偏离最终代码的实际成本,这是由于对代码大小、寄存器压力、调用开销、堆栈帧的成本、值传播的好处等的不准确估计。
这可能会导致这样的结论:与代码的非内联版本相比,内联函数将降低代码性能。
这通常发生在优化代码大小(-Os)时。你可以使用-Winline来诊断这种情况。有时代码实际上更糟糕,但你仍然需要内联版本,因为你更喜欢速度而不是代码大小,即使使用-Os。有时编译器的成本模型并不是100%正确。
“not suitable for inlining” 的情况下,您可以添加__attribute__((__always_inline__)),编译器将内联该函数(如果不禁止),即使关闭了优化。

相关问题