我对C和C++还很陌生,我正在努力理解函数。我遇到了一个叫做内联函数的术语,并将其理解为当一个函数被声明为内联时,编译器会在任何时候、任何地方调用该函数时将整个代码粘贴到该函数中。
我以为这实际上是函数调用时发生的情况,但现在意识到事实并非如此。
有人能详细解释一下当调用一个普通函数和一个内联函数时,编译器和系统级别会发生什么吗?
任何关于理解这一点的材料都将不胜感激。
当调用(非内联)函数时,编译器必须将函数参数/自变量放置在被调用函数期望找到它们的位置。在某些情况下,它会将参数"推"到进程/线程的堆栈上。在其他情况下,CPU寄存器可能被分配给特定的参数。然后,"返回地址"或被调用函数后面的地址被推送到堆栈上,这样被调用函数就知道如何将控制权返回给调用者。
当调用内联函数时,编译器只需将函数编织到代码中。调用方和被调用方之间不需要关于参数放置位置的通用协议。"return"语句(在被调用的内联函数中)通常由编译器实现,以跳转到内联代码后面的下一条指令。
如果在代码中多次调用内联函数,将导致代码大小增加。然而,进行内联调用通常比进行函数调用便宜(在cpu周期内)。
当程序调用函数时,程序控制权会转移到被调用的函数。被调用的函数执行定义的任务,当执行其返回语句时,或者当达到其函数结尾的大括号时,它将程序控制返回到主程序。
试试这个https://softwareengineering.stackexchange.com/questions/195385/understanding-stack-frame-of-function-call-in-c-c——对于正常功能工作行为
对于内联函数如何在调用位置替换内联函数代码?
函数调用不是免费的,尤其是在perf-critic部分(例如事件循环)。旧堆栈地址、新函数参数、时间和返回值。当您生成func时,正在被推送到堆栈。调用,这可能会导致您丢失一些来自CPU的时钟。
除非它不是代码中非常关键的部分,否则不要担心编译器会内联它(如果可以的话)。但是,如果它是经常运行的代码的一部分(比如while(true)循环之类的),您可以尝试强制编译在没有func的情况下复制粘贴代码。通过在函数的开头指示inline来调用。
最后一句话,如果你试图内联所有函数。您可能最终会出现缓存未命中等情况,性能更差。让编译器为您优化它,除了代码的致命部分。