Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在C+中没有强制内联的标准方法+;?_C++_Standards_Inline Code - Fatal编程技术网

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

C++ 为什么在C+中没有强制内联的标准方法+;?,c++,standards,inline-code,C++,Standards,Inline Code,根据 C++是为程序员提供选择而设计的,即使这可能使程序员做出错误的选择 如果它是这样设计的,为什么即使我可能错了,也没有标准的方法来强制编译器内联一些东西 或者我可以问为什么inline关键字只是一个提示 我想我在这里别无选择 在OOP世界中,我们应该避免对对象调用方法和直接访问成员。如果我们不能强制访问器内联,那么我们就无法编写高性能但仍然可维护的应用程序 (我知道许多编译器实现了自己的强制内联方式,但这很难看。使用宏在类上生成内联访问器也很难看。) 编译器是否总是比程序员做得更好?编译器如

根据

C++是为程序员提供选择而设计的,即使这可能使程序员做出错误的选择

如果它是这样设计的,为什么即使我可能错了,也没有标准的方法来强制编译器内联一些东西

或者我可以问为什么
inline
关键字只是一个提示

我想我在这里别无选择

在OOP世界中,我们应该避免对对象调用方法和直接访问成员。如果我们不能强制访问器内联,那么我们就无法编写高性能但仍然可维护的应用程序

(我知道许多编译器实现了自己的强制内联方式,但这很难看。使用宏在类上生成内联访问器也很难看。)


编译器是否总是比程序员做得更好?

编译器如何内联递归函数(特别是如果编译器不支持尾部调用优化,即使它支持,函数也不支持尾部调用优化)


这只是编译器决定内联是否实用的一个原因。还有一些我现在想不起来的问题。

如果你真的需要强制内联函数(为什么?),你可以这样做:复制并粘贴代码,或者使用宏

或者我可以问为什么内联关键字是 只是一个暗示

因为你“可能”比编译器更懂

大多数情况下,对于未标记为内联(且未正确声明/定义)的函数,编译器将根据其配置和实现自行计算函数是否可以内联

例如,如果代码不长和/或太复杂,大多数编译器将自动内联在头中完全定义的成员函数。这是因为函数在标题中可用,为什么不尽可能多地内联它呢? 但是,这不会发生,例如,在Visual Studio的调试模式下:在调试中,调试信息仍然需要映射函数的二进制代码,因此它避免内联,但仍然会内联标记为内联的函数,因为用户需要它。如果您想在调试时获得更好的性能的同时,标记不需要调试时间信息(如简单的getter)的函数,这将非常有用。 在发布模式下(默认情况下),编译器将积极地内联它所能做的一切,使得调试代码的某些部分变得更加困难,即使您激活了调试信息

因此,一般的想法是,如果您以有助于编译器内联的方式编写代码,它将尽可能多地内联。如果您以难以或不可能内联的方式编写代码,它将避免。如果您将某个内容标记为内联,您只需告诉编译器,如果它发现内联很困难但并非不可能,那么它应该内联它

因为内联依赖于调用方和被调用方的上下文,所以没有“规则”。 通常建议直接忽略显式标记函数inline,但有两种情况:

  • 如果需要将函数定义放在头中,只需将其内联即可;通常情况下,模板(成员或非成员)函数和其他只是快捷方式的实用程序函数
  • 如果您希望特定编译器在编译时以特定的方式运行,例如,即使在VisualStudio编译器的调试配置中,也要将某些内联成员函数标记为内联
  • 编译器总是做得更好吗 而不是程序员

    不,这就是为什么有时使用内联关键字会有所帮助。程序员有时可以比编译器更全面地了解所需的内容。例如,如果程序员希望它的二进制文件尽可能小,这取决于代码,内联可能是有害的。在需要速度和性能的应用程序中,积极的内联非常有用。编译器如何知道需要什么?必须对它进行配置,并允许它以精细的方式知道真正需要内联的内容

    编译器总是比程序员做得更好吗

    不,不总是。。。但是程序员更容易出错,并且不太可能在几年内保持最佳调优。底线是,内联只有在函数非常小(至少对于一个常见/重要的代码路径)的情况下才有助于提高性能,但是它可以帮助提高大约一个数量级,当然这取决于很多事情。对于程序员来说,评估一个函数的重要性往往是不切实际的,更不用说仔细观察它了,而且阈值会随着编译器实现选择、命令行选项、CPU模型等的不同而变化。。有太多的事情可能会突然膨胀一个函数-任何非内置类型都可能触发各种不同的行为(尤其是在模板中),操作符的使用(甚至
    new
    )可能会过载,调用约定和异常处理步骤的冗长性对于程序员来说通常并不明显

    如果编译器没有内联一些足够小的东西,如果它是内联的,那么编译器可能会意识到一些实现问题,而这些问题实际上会使情况变得更糟。在这些灰色的情况下,编译器可能会走任何一条路,而您刚刚超过某个阈值,那么性能差异无论如何都不太可能显著

    此外,一些程序员(包括我自己)可能会懒惰,故意滥用
    inline
    ,将实现放在头文件中,绕过ODR,即使他们知道这些函数很大,而且如果编译器(被要求)实际将它们内联,这将是灾难性的。但这并不排除强制内联关键字/符号。。。它只是解释了为什么很难改变当前
    内联
    关键字的期望值。