9

以下代码有什么不同:

class Foo  
{
  inline int SomeFunc() { return 42; }
  int AnotherFunc() { return 42; }
};

这两个函数都会被内联吗?内联实际上有什么不同吗?关于何时应该或不应该内联代码是否有任何规则?我经常使用AnotherFunc语法(例如访问器),但很少inline直接指定。

4

9 回答 9

26

inline关键字本质上是对编译器的提示。使用inline并不能保证你的函数被内联,也不能保证它不会被内联。您只是让编译器知道,更努力地内联该特定函数可能是一个好主意。

于 2008-09-17T19:17:39.730 回答
16

两种形式都应该以完全相同的方式内联。对于类定义中定义的函数体,内联是隐式的。

于 2008-09-17T19:17:08.203 回答
6

Sutter 的本周 Guru #33 回答了您的一些问题以及更多问题。

http://www.gotw.ca/gotw/033.htm

于 2008-09-17T19:18:35.530 回答
3
class Foo  
{
  inline int SomeFunc() { return 42; }
  int AnotherFunc() { return 42; }
};

两种方式都保证编译相同是正确的。但是,最好不要采用这两种方式。根据C++ 常见问题解答,您应该在类定义中正常声明它,然后在类定义之外,在标头内使用显式inline关键字定义它。正如FAQ所描述的,这是因为您想将声明和定义分开以使其他人的可读性(声明相当于“什么”和定义“如何”)。

内联实际上有什么不同吗?

是的,如果编译器允许内联请求,那就大不相同了。将内联代码视为宏。在调用它的任何地方,函数调用都会被函数定义中的实际代码替换。如果您内联大型函数,这可能会导致代码膨胀,但是如果函数太大,编译器通常会通过不授予内联请求来保护您免受这种情况的影响。

关于何时应该或不应该内联代码是否有任何规则?

我不知道任何硬性+快速的规则,但是如果经常调用并且相对较小,则指导方针是仅内联代码。Setter 和 getter 通常是内联的。如果它位于代码的性能特别密集的区域,则应考虑内联。永远记住,你是用内联来换取可执行文件大小的执行速度。

于 2008-09-17T20:58:02.017 回答
2

如果您认为自己比编译器更了解, VC++ 支持__forceinline__declspec(noinline)指令。提示:你可能不知道!

于 2008-09-17T19:23:03.913 回答
2

内联是编译器提示,并不强制编译器内联代码(至少在 C++ 中)。因此,简短的回答是它是编译器,并且可能取决于您的示例中将发生的情况。大多数优秀的编译器可能会内联两者,特别是由于两个函数的恒定返回的明显优化。

一般来说,内联不是您应该担心的事情。它带来了不必执行机器指令来生成堆栈帧和返回控制流的性能优势。但除了最专业的情况外,我认为这都是微不足道的。

内联在两种情况下很重要。如果您处于实时环境中并且响应速度不够快,则可以使用。二是如果代码分析在一个非常紧凑的循环中显示出明显的瓶颈(即,一个反复调用的子程序),那么内联可能会有所帮助。

特定的应用程序和架构也可能导致您将内联作为优化。

于 2008-09-17T19:23:57.187 回答
1

如果内联被省略,我发现一些 C++ 编译器(即 SunStudio)会抱怨

int AnotherFunc() { return 42; }

所以我建议在这种情况下总是使用 inline 关键字。如果您稍后将该方法实现为实际的函数调用,请不要忘记删除 inline 关键字,这会真正搞乱链接(在 SunStudio 11 和 12 以及 Borland C++ Builder 中)。我建议尽量少使用内联代码,因为当使用调试器单步执行代码时,即使使用“跳过”命令,它也会“进入”内联代码,这可能会很烦人。

于 2008-09-17T21:36:59.897 回答
0

请注意,在类之外,inline在代码中做了一些更有用的事情:通过强制(嗯,有点)C++ 编译器在每次调用函数时生成内联代码,它可以防止同一符号的多个定义(函数签名) 在不同的翻译单元中。

因此,如果您在头文件中内联非成员函数,并将其包含在多个 cpp 文件中,则链接器不会对您大喊大叫。如果函数太大而无法建议内联,请使用 C 方式:在 header 中声明,在 cpp 中定义。

这与代码是否真的内联无关:它允许在头文件中实现样式,这对于短成员函数很常见。

(我想如果编译器需要函数的非内联渲染,它会很聪明,就像模板函数一样,但是......)

于 2008-09-18T01:22:20.477 回答
0

另外补充一下 Greg 所说的,在执行优化(即inline-ing)时,编译器不仅会参考代码中的关键字,还会参考其他命令行参数,以指定编译器应如何优化代码。

于 2008-09-18T04:53:46.537 回答