或者我可以问为什么 inline 关键字只是一个提示?
因为你“可能”比编译器更了解。
大多数时候,对于未标记为内联(并且正确声明/定义)的函数,编译器将根据其配置和实现自行评估该函数是否可以内联。
例如,如果代码不长和/或太复杂,大多数编译器将自动内联在头文件中完全定义的成员函数。那是因为函数在标题中可用,为什么不尽可能多地内联它呢?但是这不会发生,例如在 Visual Studio 的调试模式下:在调试中,调试信息仍然需要映射函数的二进制代码,因此它避免内联,但仍会内联标记为内联的函数,因为用户需要它。如果你想标记函数你不需要有调试时信息(如简单的 getter)同时在调试时获得更好的性能,这很有用。在发布模式下(默认情况下),编译器将积极内联它所能做的一切,
因此,一般的想法是,如果您以有助于编译器内联的方式进行编码,它将尽可能多地内联。如果您以难以或不可能内联的方式编写代码,它将避免。如果您将某些内容标记为内联,您只需告诉编译器,如果它发现很难内联但并非不可能内联,则应将其内联。
由于内联取决于调用者和被调用者的上下文,因此没有“规则”。通常建议的是简单地忽略显式内联标记函数,但在两种情况下:
- 如果您需要将函数定义放在标题中,则只需内联即可;模板(成员或非成员)函数和其他只是快捷方式的实用函数通常是这种情况;
- 例如,如果您希望特定编译器在编译时以特定方式运行,例如将某些成员函数标记为内联,即使在 Visual Studio 编译器的调试配置中也是如此。
编译器总是比程序员做得更好吗?
不,这就是为什么有时使用 inline 关键字会有所帮助的原因。程序员有时可以比编译器更好地了解什么是必要的。例如,如果程序员希望它的二进制文件尽可能小,这取决于代码,内联可能是有害的。在需要速度性能的应用程序中,积极地内联会很有帮助。编译器如何知道需要什么?必须对其进行配置并允许以细粒度的方式了解真正想要内联的内容。