内联C ++代码
以下代码有什么区别:
class Foo { inline int SomeFunc() { return 42; } int AnotherFunc() { return 42; } };
这两个函数都会内联吗?内联实际上有什么区别吗?关于何时应该内联代码或者不应该内联代码有任何规定吗?我经常使用" AnotherFunc"语法(例如访问器),但是我很少直接指定" inline"。
解决方案
回答
两种形式都应以完全相同的方式内联。对于类定义中定义的功能体,内联是隐式的。
回答
inline关键字本质上是对编译器的提示。使用inline
并不能保证函数会被内联,也不能保证不会。我们只是让编译器知道,尝试内联该特定函数可能是个好主意。
回答
Sutter的本周大师#33回答了一些问题,甚至更多。
http://www.gotw.ca/gotw/033.htm
回答
如果我们认为自己比编译器更了解,则VC ++支持__forceinline和__declspec(noinline)指令。提示:我们可能不知道!
回答
内联是编译器提示,并不强制编译器内联代码(至少在C ++中)。因此,简短的答案是它是编译器,并且可能取决于上下文,在示例中将发生什么。大多数优秀的编译器都可能内联这两个函数,尤其是由于明显优化了两个函数的常量返回值。
通常,内联不是我们应该担心的事情。它带来了不必执行机器指令即可生成堆栈框架和返回控制流的性能优势。但是,除了最特殊的情况外,我认为这都是微不足道的。
内联在两种情况下很重要。如果我们处于实时环境中,并且响应速度不够快,则该为一种。二是如果代码分析在一个非常紧密的循环中(即,一遍又一遍的子例程)显示出明显的瓶颈,那么内联会有所帮助。
特定的应用程序和体系结构也可能导致我们进行内联优化。
回答
class Foo { inline int SomeFunc() { return 42; } int AnotherFunc() { return 42; } };
两种方法都可以保证编译相同是正确的。但是,最好不采用这两种方式。根据C ++ FAQ,我们通常应该在类定义中声明它,然后在该类定义之外的标头中使用显式inline关键字进行定义。正如FAQ所描述的,这是因为我们想将声明和定义分开,以使其他人易于理解(声明等同于" what"和定义" how")。
Does inline actually make any difference?
是的,如果编译器准许内联请求,则有很大的不同。将内联代码视为宏。在调用的任何地方,函数调用都将替换为函数定义中的实际代码。如果内联大型函数,这可能导致代码膨胀,但是如果函数太大,编译器通常通过不授予内联请求来保护我们免受此侵害。
Are there any rules on when you should or shouldn't inline code?
我不知道任何硬性规则,但是指南是仅内联代码(如果经常调用且相对较小)。 Setter和getter通常是内联的。如果它在代码的性能特别密集的区域中,则应考虑内联。永远记住,我们正在以内联方式交换可执行文件大小的执行速度。
回答
我发现一些C ++编译器(例如SunStudio)抱怨如果内联被省略,如
int AnotherFunc() { return 42; }
因此,在这种情况下,我建议始终使用inline关键字。而且,如果以后将该方法实现为实际的函数调用,请不要忘记删除inline关键字,这确实会搞乱链接(在SunStudio 11和12和Borland C ++ Builder中)。
我建议尽量少用内联代码,因为当使用调试器逐步执行代码时,即使使用" step over"命令,它也会"进入"内联代码,这可能会很烦人。
回答
请注意,在类之外,"内联"在代码中做的事情更有用:通过强制(好,某种程度上)C ++编译器在每次调用函数时内联生成代码,从而防止了同一符号的多个定义(功能签名)在不同的翻译单元中。
因此,如果我们将非成员函数内联到头文件中,并将其包含在多个cpp文件中,则链接器不会大吼大叫。如果该函数太大而不能建议内联,请使用C方法:在标头中声明,在cpp中定义。
这与代码是否真正内联几乎没有关系:它允许在标头中实现样式,这是短成员函数所常见的。
(我想如果编译器需要该函数的非内联呈现(例如用于模板函数)将很聪明,但是...)
回答
此外,Greg补充说,在执行优化(即"内联")时,编译器不仅会查询代码中的关键字,还会查询其他命令行参数,从而指定编译器应如何优化代码。