在c++中使用内联函数的优点/缺点是什么?我看到它只提高了编译器输出的代码的性能,但随着今天优化的编译器,快速的cpu,巨大的内存等(不像在1980年<内存是稀缺的,所有东西都必须适合100KB内存),他们今天真正有什么优势?


当前回答

我想补充一点,在构建共享库时,内联函数是至关重要的。如果不将函数标记为内联,则它将以二进制形式导出到库中。如果导出,它也将出现在符号表中。另一方面,内联函数不会被导出,既不会被导出到库二进制文件中,也不会被导出到符号表中。

当库打算在运行时加载时,它可能是关键的。它还可能打击二进制兼容的库。在这种情况下,不要使用内联。

其他回答

内联函数更快,因为你不需要将参数和返回地址等东西推入或弹出堆栈;但是,它确实会使二进制文件略大一些。

有显著的区别吗?对大多数人来说,在现代硬件上还不够明显。但它可以产生影响,这对一些人来说已经足够了。

将某些东西标记为内联并不能保证它将是内联的。这只是给编译器的一个建议。有时候是不可能的比如你有一个虚函数,或者涉及到递归。有时候编译器会选择不使用它。

我可以看到这样的情况会产生明显的不同:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

内联是对编译器的一个建议,它可以随意忽略。它非常适合小段代码。

如果你的函数是内联的,它基本上是插入到函数调用的代码中,而不是实际调用一个单独的函数。这有助于提高速度,因为你不必实际打电话。

它还帮助cpu进行流水线操作,因为它们不必用调用引起的新指令重新加载流水线。

唯一的缺点是可能会增加二进制大小,但只要函数很小,这就不会太大。

现在我倾向于把这类决定留给编译器(好吧,至少是聪明的编译器)。编写它们的人往往对底层架构有更详细的了解。

在将函数内联到so库时遇到了同样的麻烦。似乎内联函数没有编译到库中。因此,如果一个可执行文件想要使用库的内联函数,链接器会输出一个“未定义引用”错误。(我碰巧用gcc 4.5编译Qt源代码。

在优化过程中,许多编译器会内联函数,即使你没有标记它们。如果你知道一些编译器不知道的东西,你通常只需要将函数标记为内联,因为它自己通常可以做出正确的决定。

我想补充一点,在构建共享库时,内联函数是至关重要的。如果不将函数标记为内联,则它将以二进制形式导出到库中。如果导出,它也将出现在符号表中。另一方面,内联函数不会被导出,既不会被导出到库二进制文件中,也不会被导出到符号表中。

当库打算在运行时加载时,它可能是关键的。它还可能打击二进制兼容的库。在这种情况下,不要使用内联。