在c++中使用内联函数的优点/缺点是什么?我看到它只提高了编译器输出的代码的性能,但随着今天优化的编译器,快速的cpu,巨大的内存等(不像在1980年<内存是稀缺的,所有东西都必须适合100KB内存),他们今天真正有什么优势?
当前回答
另一个讨论的结论是:
内联函数有什么缺点吗?
显然,使用内联函数并没有什么错。
但值得注意的是以下几点!
Overuse of inlining can actually make programs slower. Depending on a function's size, inlining it can cause the code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs faster due to better use of the instruction cache. - Google Guidelines The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost - Source There are few situations where an inline function may not work: For a function returning values; if a return statement exists. For a function not returning any values; if a loop, switch or goto statement exists. If a function is recursive. -Source The __inline keyword causes a function to be inlined only if you specify the optimize option. If optimize is specified, whether or not __inline is honored depends on the setting of the inline optimizer option. By default, the inline option is in effect whenever the optimizer is run. If you specify optimize , you must also specify the noinline option if you want the __inline keyword to be ignored. -Source
其他回答
内联是对编译器的一个建议,它可以随意忽略。它非常适合小段代码。
如果你的函数是内联的,它基本上是插入到函数调用的代码中,而不是实际调用一个单独的函数。这有助于提高速度,因为你不必实际打电话。
它还帮助cpu进行流水线操作,因为它们不必用调用引起的新指令重新加载流水线。
唯一的缺点是可能会增加二进制大小,但只要函数很小,这就不会太大。
现在我倾向于把这类决定留给编译器(好吧,至少是聪明的编译器)。编写它们的人往往对底层架构有更详细的了解。
在优化过程中,许多编译器会内联函数,即使你没有标记它们。如果你知道一些编译器不知道的东西,你通常只需要将函数标记为内联,因为它自己通常可以做出正确的决定。
我想补充一点,在构建共享库时,内联函数是至关重要的。如果不将函数标记为内联,则它将以二进制形式导出到库中。如果导出,它也将出现在符号表中。另一方面,内联函数不会被导出,既不会被导出到库二进制文件中,也不会被导出到符号表中。
当库打算在运行时加载时,它可能是关键的。它还可能打击二进制兼容的库。在这种情况下,不要使用内联。
在将函数内联到so库时遇到了同样的麻烦。似乎内联函数没有编译到库中。因此,如果一个可执行文件想要使用库的内联函数,链接器会输出一个“未定义引用”错误。(我碰巧用gcc 4.5编译Qt源代码。
内联允许您在头文件中放置函数定义,并在多个源文件中#包含该头文件,而不违反一个定义规则。