为什么没有标准方法强制C ++内联?

| 根据Wikipedia C ++文章   C ++旨在为程序员提供选择,即使这使程序员可能会选择错误。 如果以这种方式设计,为什么即使我可能是错的,也没有标准的方法来强制编译器内联某些东西? 或者我可以问为什么
inline
只是一个提示? 我想我在这里别无选择。 在OOP世界中,我们在对象上调用方法,应避免直接访问成员。如果我们不能强制访问器内联,那么我们将无法编写高性能但仍可维护的应用程序。 (我知道许多编译器都实现了强制内联的方式,但这很丑陋。使用宏在类上进行内联访问器也很丑陋。) 编译器是否总是比程序员做得更好?     
已邀请:
编译器如何内联递归函数(尤其是如果编译器不支持尾调用优化,即使编译器不支持尾调用优化,该函数也不行)。 这只是编译器应决定内联是否可行的原因之一。可能还有其他我现在想不起来的东西。     
  编译器是否总是比程序员做得更好? 不,并非总是如此……但是程序员更容易出错,并且在过去的几年中保持最佳调整的可能性较小。最重要的是,内联仅在函数真的很小时(对于至少一个公共/重要的代码路径)才有助于提高性能,但是取决于很多事情,它可以帮助一个数量级。对于程序员来说,评估通常是不切实际的,更不用说仔细看函数的琐碎性了,并且阈值会随编译器实现选择,命令行选项,CPU模型等的不同而变化。有很多事情可能突然膨胀了一个函数-任何非内置类型都可以触发各种不同的行为(尤其是模板中的esp),运算符的使用(甚至是
new
)可能会被重载,调用约定和异常处理步骤的详细程度通常不高对程序员来说很明显。 机会是,如果编译器没有内联足够小的内容,如果内联了它,您就可以期望获得有用的性能改进,那么编译器意识到某些实现问题,您不是那样做的。实际上使情况变得更糟。在那些灰色的情况下,编译器可能会选择哪种方式运行,而您刚刚超过某个阈值,那么性能差异无论如何都不会很明显。 此外,有些程序员(包括我自己)可能会懒惰并故意滥用ѭ0作为将实现放在头文件中的便捷方法,从而绕过ODR,即使他们知道那些函数很大并且如果编译器会造成灾难性的后果(被要求)实际上内联它们。但这并不排除强制内联关键字/表示法...只是说明了为什么很难更改当前“ 0”关键字周围的期望。     
或者我可以问为什么内联关键字是   只是一个提示? 因为您“可能”比编译器了解更多。 在大多数情况下,对于未标记为内联(且未正确声明/定义)的函数,编译器将根据其配置和实现自行评估该函数是否可以内联。 例如,如果代码不是很长和/或太复杂,大多数编译器会自动内联在标头中完全定义的成员函数。那是因为当标头中提供该函数时,为什么不尽量内联它呢? 但是,这不会发生,例如,在Visual Studio的Debug模式下:在Debug中,调试信息仍然需要映射函数的二进制代码,因此它避免了内联,但仍将内联函数标记为inline,因为用户需要它。如果您想标记函数,而无需在调试时获得更好的性能的同时不需要调试时信息(例如简单的getter),则这很有用。 在发布模式下(默认情况下),编译器将尽可能地内联所有内容,即使激活了调试信息,也很难调试部分代码。 因此,一般的想法是,如果您以有助于编译器内联的方式进行编码,则它将尽可能内联。如果以难以内联或不可能内联的方式编写代码,则可以避免。如果将内容标记为内联,则只是告诉编译器,如果发现内联困难但并非不可能,则应内联。 由于内联取决于调用方和被调用方的上下文,因此没有“规则”。 通常建议只在两种情况下忽略显式标记函数内联: 如果需要将函数定义放在标头中,则只需内联;模板(成员或不成员)功能以及其他只是快捷方式的实用程序功能通常会出现这种情况; 如果您希望特定的编译器在编译时以特定的方式运行,例如将某些成员函数标记为内联,即使在Visual Studio编译器上的Debug配置中也可以内联。   编译器是否总是做得更好   比程序员? 不,这就是为什么有时使用内联关键字可以有所帮助的原因。程序员有时可以比编译器更好地了解所需的内容。例如,如果程序员希望二进制文件尽可能小,则取决于代码,内联可能有害。在需要速度性能的应用程序中,积极地进行内联会很有帮助。编译器将如何知道需要什么?必须对其进行配置,并允许其以细粒度的方式知道真正想要内联的内容。     
错误的假设。 有一种方法。拼写为
#define
。对于许多早期的C项目,这已经足够了。
inline
是足够不同的-提示,更好的语义-可以在宏之外添加。但是,一旦两者兼而有之,则之间的第三种选择就几乎没有余地了,这三种选择具有更好的语义,但不是可选的。     
如果确实需要强制执行函数的内联(为什么?),则可以执行此操作:复制代码并粘贴它,或使用宏。     

要回复问题请先登录注册