C内联函数和内存使用

7
如果我使用内联函数,内存使用量会增加吗?

一般情况下这个问题无法回答。如果你有具体的例子,可以尝试一下看会发生什么。 - Martin York
8个回答

10

有两种内联函数会影响的内存使用:

代码大小 — 通常来说,内联代码会增加程序加载时所需的内存使用量。这是因为生成的代码会散布在程序中的多个位置。但是,并非总是如此--如果您的内联函数只使用一次,则变化很小;如果内联函数非常小,则可以通过删除函数调用开销来获得净减少的代码大小。另外,优化器可能会缩小函数的大小,以便删除特定内联调用中未使用的代码。

堆栈使用 — 如果您的内联函数有大量本地变量,则可能会使用更多的堆栈空间。在 C 中,编译器通常在进入函数时一次性分配函数的堆栈空间。这必须足够大,以容纳所有未存储在寄存器中的本地变量。如果调用一个非内联函数,则该函数的堆栈将在返回时被释放。如果内联该函数,则该堆栈空间将在整个超级函数的生命周期内保持使用。

内联不会影响堆使用情况,因为对于内联代码和非内联版本,相同的分配和释放操作都会发生。


6

还有一点需要考虑:

使用内联函数,编译器能够看到调用者的变量在被调用者中作为变量使用的位置。基于这种知识,编译器可以优化掉(通常这确实是可以省略的许多汇编行。请注意所谓的“别名问题”)冗余代码。因此,你的“代码膨胀”通常并不是很大,特别是如果你有较小的函数,它甚至可以减少膨胀,就像Jim上面所说的那样。

有人提出了一个很好的观点:最好让编译器决定是否内联所涉及的函数,因为它比你更了解所生成的代码。


2

取决于函数。简单的一行代码可能会减少内存,因为不需要设置和清除调用堆栈,也不需要进行函数调用。如果函数比调用函数所需的开销大,则会使代码膨胀。


2

一般情况下,这是一个无法回答的问题。

首先,您通常无法控制内联。即使您将函数标记为inline,实际上是否进行内联仍由编译器决定(这只是一个提示)。

编译器会尽其所能优化代码;使用内联只是其中之一。因此,内联短函数将使代码更小(因为您不需要设置调用的参数或检索返回值)。但是,即使对于长函数,答案也不是绝对的。

如果编译器决定内联一个长函数,那么您可能认为代码会变得更长。但通常情况下并非如此;因为这给编译器提供了额外的机会来应用其他可能使代码仍然更小的优化技术。如果编译器的分析发现结果代码膨胀对代码有害,则不会进行内联。

基本上,编译器会进行分析并决定最佳操作方式。

结论:不要担心。编译器比您聪明,并且会做正确的事情。


1

内联函数肯定会增加最终可执行文件(或二进制文件)的大小,因为它们将在调用它们的任何地方被“复制粘贴”。


抱歉,您的答案不完整,并且已经包含在上面的答案中。 - Randy Stegbauer

0
您的程序通常会变得更加庞大(当然可能有例外情况)。运行时内存消耗可能会降低,但并不会很多。
为什么您要询问呢?通常情况下,您应该让编译器决定一个函数是否应该被内联;它能根据函数的大小和复杂度做出更好的判断。

0

一个函数调用需要多个处理器指令。

通常,每个参数都需要一个PUSH指令来调用函数,一个CALL指令来调用函数,以及在函数调用后清理堆栈的另一个指令。

此外,函数可能会修改处理器的寄存器,因此调用函数的函数可能需要更多的指令来保留寄存器或重新加载否则仍然在寄存器中的值。

因此,如果您要调用的函数只有几个指令长,内联可以节省内存并且运行更快。

话虽如此,内联是在分析器告诉您应该这样做时使用的。


C定义了一个ABI,其中所有参数都被推送到堆栈。C ++没有定义特定的ABI,允许编译器实现使用寄存器进行参数传递。因此,在大多数情况下,并不是所有参数都会被推送到堆栈中。 - Martin York

0
有时候我们会在程序中散布各种函数。在这种情况下,函数调用会导致程序跳转到函数的地址,并在函数调用终止时返回。这需要花费一些宝贵的时间。
使用内联函数可以解决上述问题。这会使编译器直接从源代码调用代码。对于内联函数代码,不会创建新的内存指令集。
虽然在C++中内联声明是免费的,并且在声明中定义函数时自动发生,但在C语言中,它受以下规则限制:
  1. 在C语言中,任何具有内部链接的函数都可以声明为内联函数,但具有外部链接的函数对内联函数有限制。
  2. 如果在函数声明中使用了inline关键字,则函数定义应该存在于同一个翻译单元中。
内联数据类型函数名(参数)
与非内联函数相比,此代码运行速度快30%,其余取决于处理器速度。
现在进入策略部分。您可以随意使用内联函数,但要记住,内联函数执行时间可能会更短,但运行时内存占用率较高。此外,如果声明为内联的代码与代码大小相比异常大,则编译器始终有忽略内联声明的选项。
尽管内联声明破坏了评估顺序,但并不使函数成为内部函数。该函数仍然是外部函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接