C内联函数和内存使用

时间:2008-11-11 06:38:42

标签: c inline-method

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

8 个答案:

答案 0 :(得分:8)

内联函数会影响两种内存使用情况:

代码大小 - 通常,内联代码会增加用于加载程序的内存量。这是因为在程序周围会分散生成的代码的多个副本。但是,并非总是如此 - 如果内联函数仅使用一次,则几乎没有变化,如果内联函数非常小,则可以通过删除函数调用开销来减少代码大小。此外,优化器可以减小函数的大小,该优化器能够删除特定内联调用中未使用的代码。

堆栈使用 - 如果内联函数有很多局部变量,那么您可能会使用更多堆栈空间。在C中,编译器通常在进入函数时为函数分配一个堆栈空间。这必须足够大以容纳未存储在寄存器中的所有局部变量。如果您在线外调用函数,则会使用该函数的堆栈,直到它再次释放为止。如果你内联函数,那么该堆栈空间将在超级函数的整个生命周期中保持使用。

内联不会影响堆使用,因为内联代码会发生与非内联版本相同的分配和解除分配。

答案 1 :(得分:6)

还有一点需要考虑:

使用内联函数,编译器能够查看调用者的变量将在被调用者中用作变量的位置。编译器可以优化(通常这是很多可以省略的汇编器行。注意所谓的“别名问题”)基于该知识的冗余代码。因此,你的“代码臃肿”往往不是那么大,特别是如果你有更小的功能,它甚至可以减少膨胀,正如Jim所说。

有人提出了一个好主意:更好地让编译器决定是否内联有问题的函数,因为它比以往更了解它生成的代码。

答案 2 :(得分:2)

取决于功能。简单的单行可以减少内存,因为不需要设置和清理callstack,也不会进行函数调用。如果函数大于调用函数所需的开销,那么它当然会膨胀代码。

答案 3 :(得分:2)

在一般情况下,这确实无法回答。

首先,您通常无法控制内衬。即使你将函数标记为内联,它实际上仍然取决于编译器的枯萎,它实际上会进行内联(这只是一个提示)。

编译器将尽力优化代码;使用内衬只是这样做的一个工具。因此,内联短函数会使代码变小(因为您不需要为调用设置参数或检索返回值。但即使使用长函数,答案也不是绝对的。

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

编译器基本上会进行分析并决定最佳行动方案。

结论。别担心。编译器比你更聪明,并且会做正确的事情。

答案 4 :(得分:1)

内联函数肯定会增加最终可执行文件(或二进制文件)的大小,因为只要您调用它们,它们就会被“复制粘贴”。

答案 5 :(得分:0)

你的程序在一般情况下会变大(我确定有例外)。运行时内存消耗可能会下降,但不会太多。

你为什么问?通常,您让编译器确定是否应该内联函数;考虑到函数的大小和复杂性,它通常可以做出更好的调用。

答案 6 :(得分:0)

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

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

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

因此,如果您调用的函数只是一些指令,则内联它可以节省内存运行得更快。

也就是说,内联是指你的探查者告诉你应该的时候。

答案 7 :(得分:0)

有时会发生我们在整个程序中散布的函数。在这种情况下,函数调用会导致程序跳转到函数的地址,并在函数调用终止时返回。这消耗了一些宝贵的时间。

使用内联函数可以解决上述问题。这会导致编译器直接从源代码调用代码。没有为内联函数代码创建新的内存指令集。

虽然c ++中的内联声明是免费的,并且在声明中定义函数时自动发生,但在c中它受以下规则限制::

  1. 在C中,任何具有内部链接的函数都可以内联声明,但具有外部链接的函数对内联有限制。

  2. 如果在函数声明中使用了inline关键字,那么函数定义应该出现在同一个翻译单元中。

  3. 内联数据类型function_name(arguments)

    此代码比非内联函数运行高达30%,其余部分取决于先行速度。

    现在是战略部分。您可以随意使用内联函数,但请记住,内联函数执行的时间要少得多,但运行时内存占用率很高。如果声明内联的代码与代码大小相比异常大,编译器也始终可以忽略内联声明。

    内联声明虽然破坏了评估的顺序,但却没有使函数内部化。该功能仍在外部。