以下代码有什么不同:
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
两个函数都会被内联吗?内联实际上有什么区别吗?关于何时应该或不应该内联代码,是否有任何规则?我经常使用AnotherFunc
语法(例如访问器),但我很少直接指定inline
。
答案 0 :(得分:26)
inline
关键字本质上是编译器的提示。使用inline
并不能保证您的函数将内联,也不能保证它不会。您只是让编译器知道尝试更难以内联该特定函数可能是个好主意。
答案 1 :(得分:16)
两种表格都应以完全相同的方式内联。对于在类定义中定义的函数体,内联是隐含的。
答案 2 :(得分:6)
Sutter的本周大师#33回答了你的一些问题以及更多问题。
答案 3 :(得分:3)
class Foo
{
inline int SomeFunc() { return 42; }
int AnotherFunc() { return 42; }
};
两种方式保证编译相同是正确的。但是,最好不要采用这两种方式。根据{{3}},您应该在类定义中正常声明它,然后使用显式 inline 关键字在标题内的类定义之外定义它。正如FAQ所描述的那样,这是因为你想要为其他人的可读性分离声明和定义(声明等同于“what”和定义“how”)。
内联实际上有什么不同吗?
是的,如果编译器授予内联请求,则会有很大的不同。将内联代码视为宏。调用它的任何地方,函数调用将替换为函数定义中的实际代码。如果你内联大型函数,这可能导致代码膨胀,但是如果函数太大,编译器通常会通过不授予内联请求来保护你。
是否应该或不应该内联代码?
我不知道任何硬+快速规则,但是如果经常调用并且它相对较小,则指南仅用于内联代码。通常内联插件和getter。如果它位于代码的特别性能密集区域,则应考虑内联。永远记住,您正在使用内联交换可执行文件大小的执行速度。
答案 4 :(得分:2)
如果您认为自己比编译器更了解,VC ++支持__forceinline和__declspec(noinline)指令。提示:你可能没有!
答案 5 :(得分:2)
Inline是一个编译器提示,并不强制编译器内联代码(至少在C ++中)。所以简短的回答是它的编译器,可能与上下文有关,在你的例子中会发生什么。大多数好的编译器都可能内联,特别是由于两个函数的常量返回的明显优化。
一般来说内联不是你应该担心的事情。它带来了不必执行机器指令来生成堆栈帧和返回控制流的性能优势。但除了最专业的案例外,我认为这是微不足道的。
在两种情况下,内联很重要。如果您处于实时环境并且响应速度不够快,那就是一个。第二,如果代码分析在一个非常紧密的循环中显示出一个重要的瓶颈(即一个被称为反复的子程序),那么内联可能有所帮助。
特定的应用程序和体系结构也可能会引导您将内联作为优化。
答案 6 :(得分:1)
如果内省被省略,我发现一些C ++编译器(即SunStudio)抱怨
int AnotherFunc() { return 42; }
所以我建议在这种情况下始终使用inline关键字。如果您稍后将该方法实现为实际函数调用,请不要忘记删除内联关键字,这实际上会破坏链接(在SunStudio 11和12以及Borland C ++ Builder中)。 我建议尽可能少地使用内联代码,因为当使用调试器逐步执行代码时,即使使用“step over”命令,它也会“进入”内联代码,这可能会令人讨厌。
答案 7 :(得分:0)
请注意,在类之外,inline
在代码中做了一些更有用的事情:强制(好吧,排序)C ++编译器在每次调用函数时内联生成代码,它会阻止多个定义不同翻译单元中的相同符号(功能签名)。
因此,如果您在头文件中内联一个非成员函数,并将其包含在多个cpp文件中,则表示您没有链接器对您大喊大叫。如果函数太大而无法建议内联,请按C方式执行:在标题中声明,在cpp中定义。
这与代码是否真正内联无关:它允许在头文件中实现样式,这对于短成员函数来说很常见。
(我想如果需要函数的非内联呈现,编译器将是智能的,就像模板函数一样,但是......)
答案 8 :(得分:0)
另外要补充Greg所说的,在执行优化时(即inline
- ),编译器不仅会参考代码中的关键字,还会参考其他命令行参数,指定编译器应如何优化代码