什么时候我应该写关键字内联的函数/方法在c++ ?

在看到一些答案后,一些相关的问题:

在c++中,什么时候我不应该为函数/方法写关键字“内联”? 什么时候编译器不知道什么时候使一个函数/方法'内联'? 当一个应用程序为一个函数/方法写“内联”时,它是否重要?


当前回答

在c++中,什么时候我不应该为函数/方法写关键字“内联”?

如果函数在头文件中声明,并在.cpp文件中定义,则不应编写关键字。

什么时候编译器不知道什么时候使一个函数/方法'内联'?

没有这种情况。编译器不能使函数内联。它所能做的就是内联对函数的部分或所有调用。如果它没有函数的代码,它就不能这样做(在这种情况下,链接器需要这样做,如果它能够这样做的话)。

当一个应用程序为一个函数/方法写“内联”时,它是否重要?

不,那完全不重要。

其他回答

编译时,GCC默认不内联任何函数 启用优化。我不知道visual studio - deft_code

我检查了Visual Studio 9(15.00.30729.01)通过/FAcs编译并查看汇编代码: 编译器产生了对成员函数的调用,而没有在调试模式下启用优化。即使函数被标记为__forceinline,也不会产生内联运行时代码。

什么时候应该内联:

1.当人们想要避免调用函数时发生的开销,如参数传递,控制传递,控制返回等。

2.函数应该很小,经常被调用,并且内联是非常有利的,因为根据80-20规则,尽量使那些对程序性能有重大影响的函数内联。

正如我们所知,内联只是一个请求编译器类似于注册,它将花费你在对象代码大小。

我想用一个令人信服的例子来解释这篇文章中所有的伟大答案,以消除任何剩余的误解。

给定两个源文件,例如:

inline111.cpp: # include < iostream > 空白栏(); Inline fun() { 返回111; } Int main() { std:: cout < <“inline111:有趣 () = " << 有趣的 () << ", & 有趣= " < < (void *)与娱乐; 酒吧(); } inline222.cpp: # include < iostream > Inline fun() { 返回222; } 空格条(){ std:: cout < <“inline222:有趣 () = " << 有趣的 () << ", & 有趣= " < < (void *)与娱乐; }


Case A: Compile: g++ -std=c++11 inline111.cpp inline222.cpp Output: inline111: fun() = 111, &fun = 0x4029a0 inline222: fun() = 111, &fun = 0x4029a0 Discussion: Even thou you ought to have identical definitions of your inline functions, C++ compiler does not flag it if that is not the case (actually, due to separate compilation it has no ways to check it). It is your own duty to ensure this! Linker does not complain about One Definition Rule, as fun() is declared as inline. However, because inline111.cpp is the first translation unit (which actually calls fun()) processed by compiler, the compiler instantiates fun() upon its first call-encounter in inline111.cpp. If compiler decides not to expand fun() upon its call from anywhere else in your program (e.g. from inline222.cpp), the call to fun() will always be linked to its instance produced from inline111.cpp (the call to fun() inside inline222.cpp may also produce an instance in that translation unit, but it will remain unlinked). Indeed, that is evident from the identical &fun = 0x4029a0 print-outs. Finally, despite the inline suggestion to the compiler to actually expand the one-liner fun(), it ignores your suggestion completely, which is clear because fun() = 111 in both of the lines.


Case B: Compile (notice reverse order): g++ -std=c++11 inline222.cpp inline111.cpp Output: inline111: fun() = 222, &fun = 0x402980 inline222: fun() = 222, &fun = 0x402980 Discussion: This case asserts what have been discussed in Case A. Notice an important point, that if you comment out the actual call to fun() in inline222.cpp (e.g. comment out cout-statement in inline222.cpp completely) then, despite the compilation order of your translation units, fun() will be instantiated upon it's first call encounter in inline111.cpp, resulting in print-out for Case B as inline111: fun() = 111, &fun = 0x402980.


Case C: Compile (notice -O2): g++ -std=c++11 -O2 inline222.cpp inline111.cpp or g++ -std=c++11 -O2 inline111.cpp inline222.cpp Output: inline111: fun() = 111, &fun = 0x402900 inline222: fun() = 222, &fun = 0x402900 Discussion: As is described here, -O2 optimization encourages compiler to actually expand the functions that can be inlined (Notice also that -fno-inline is default without optimization options). As is evident from the outprint here, the fun() has actually been inline expanded (according to its definition in that particular translation unit), resulting in two different fun() print-outs. Despite this, there is still only one globally linked instance of fun() (as required by the standard), as is evident from identical &fun print-out.

在c++中,什么时候我不应该为函数/方法写关键字“内联”?

如果函数在头文件中声明,并在.cpp文件中定义,则不应编写关键字。

什么时候编译器不知道什么时候使一个函数/方法'内联'?

没有这种情况。编译器不能使函数内联。它所能做的就是内联对函数的部分或所有调用。如果它没有函数的代码,它就不能这样做(在这种情况下,链接器需要这样做,如果它能够这样做的话)。

当一个应用程序为一个函数/方法写“内联”时,它是否重要?

不,那完全不重要。

在进行模板特化时,仍然需要显式内联函数(如果特化在.h文件中)