在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

其他回答

在古老的C和c++中,内联就像寄存器:给编译器一个关于可能的优化的建议(只不过是一个建议)。

在现代c++中,内联告诉链接器,如果在不同的翻译单元中发现了多个定义(不是声明),那么它们都是相同的,链接器可以自由地保留其中一个,并丢弃所有其他的定义。

如果一个函数(无论多么复杂或“线性”)定义在头文件中,内联是强制的,以允许多个源包含它而不会被链接器产生“多个定义”错误。

默认情况下,类内部定义的成员函数是“内联”的,模板函数也是如此(与全局函数相反)。

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

注意fileA.h包含在两个.cpp文件中,导致两个afunc()实例。 链接器将丢弃其中一个。 如果没有指定inline,链接器将报错。

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

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

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

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

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);

我们的计算机科学教授敦促我们不要在c++程序中使用内联。当被问及原因时,他友好地向我们解释说,现代编译器应该自动检测何时使用内联。

是的,内联可以是一种优化技术,在任何可能的地方都可以使用,但显然这已经为你做了,只要有可能内联一个函数。

另一个讨论的结论是:

内联函数有什么缺点吗?

显然,使用内联函数并没有什么错。

但值得注意的是以下几点!

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

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