【问题标题】:How to guarantee that a function is inlined in C++如何保证函数在 C++ 中是内联的
【发布时间】:2012-07-11 09:53:39
【问题描述】:

在 C++ 中,可以使用 inline 关键字将函数定义为内联函数。就像程序员要求编译器在每个调用函数的地方插入完整的函数体一样。

但据我所知,编译器没有义务尊重这一要求。那么有没有办法保证函数是内联的呢?

【问题讨论】:

  • 我不认为你可以保证inline 关键字只是对编译器的建议。
  • 相信优化器会完成它的工作。
  • @Mike 您是否真的希望在 内联 方面比优化器更聪明?这不是现代优化师的核心能力之一吗?好的,当涉及到诸如自动矢量化和某些类型的分支预测之类的事情时,现代优化器仍然在苦苦挣扎。但是对于内联?
  • 无论如何,我同意通常没有必要这样做。我当然不会同意任何类型的说法,即它因此不值得这样做。这样的事情值得做几次,如果只是为了说服自己不值得再做一次。所以我真的不同意你之前的一些 cmets 的“盲目相信编译器”的语气。有趣的是,你的经历和 Mysticial 的直接矛盾。可能有人使用了错误的标志,否则可能你处理的代码类型非常不同,而且你的优化比他的更好。

标签: c++ inline-functions


【解决方案1】:

不。实际上内联函数是一个完整的实现细节,许多函数不能内联。这使得内联强制机制的存在成为不可能。在某些情况下,即使提供 __forceinline (VC++) 等关键字的编译器也不会使用该限定符内联函数。该页面带有关于滥用此限定符的非常恰当的警告。

【讨论】:

    【解决方案2】:

    在 VC++ 中使用 __forceinline,在 g++ 中使用 __attribute__((always_inline))

    【讨论】:

    • __forceinline 实际上根本不强制内联。阅读文档。
    • @DeadMG:据我所知,如果可能,它会强制内联;在我看来很明显,当它不可能时,没有什么可以强迫它。
    • @MikeSeymour:确实。所以答案是“无法保证”。
    • @DeadMG:对于“保证”的极端迂腐定义为“即使不可能也做”,这是正确的,但没用。对于“尽可能做”的更明智的定义,这是一个有用的答案。
    • 我更认为“保证”涉及“始终如一”。由于__forceinline 并非总是如此,因此这不是保证。它不是保证的原因很有趣,但并不能改变它不是保证的事实。
    【解决方案3】:

    由于标准未涵盖此内容,因此取决于您使用的编译器。编译器的文档将告诉您是否有强制内联函数的功能,以及如何使用它。文档还应该告诉您该功能的限制,例如非尾部位置的递归调用。

    【讨论】:

      【解决方案4】:

      如果您使用的是 Microsoft 编译器,则可以使用 __forceinline,如下所述: http://msdn.microsoft.com/en-us/library/z8y1yy88%28v=vs.71%29.aspx

      我不知道在 g++ 或其他编译器中强制内联的方法。

      【讨论】:

      • 阅读您链接的页面。它非常清楚地指出,即使使用__forceinline 实际上也不会强制编译器内联它。
      • 除了__forceinline保证编译器内联东西的建议,这绝对是错误的。
      • @DeadMG:你只是在抱怨答案没有明确说明它只有在可以内联的情况下才有效?或者你是说__forceinline 并不意味着“尽可能内联函数”。
      • 该页面已经过时了,因为它指的是 VS 2003。(希望inline 在最近的编译器中不会强制内部名称绑定。)
      • @MikeSeymour:我是说 OP 的问题是指“保证”。 __forceinline 显然有条件,但实际上并非如此。因此,它不能做出保证,也不回答问题。
      【解决方案5】:

      我无法想象有办法做到这一点。它主要依赖于编译器。另一种解决方案是使用#define 宏来定义你的函数

      【讨论】:

      • 你认为使用宏比使用内联函数有优势吗(除了你关心的这里)
      • @Kasnel:使用宏会强制内联代码(因为它是在编译前直接粘贴的);但它几乎可以肯定在大多数情况下不会带来任何优势,而且它自身也有很多缺点。
      • 好吧,至少它的交叉编译器,所以 +1,与 __forceinline 相比。它不会给你带来性能优势,但我不同意@Mike Seymour,在大多数情况下,这样的指令不会引起问题。它只是不太适合 c++
      【解决方案6】:

      通过将函数的定义直接放入头文件中的声明中,该函数被内联的机会最大。

      class TheClass
      {
      public:
          static void DoSomething () // declaration
          {
              // the function's code (definition) goes here
          };
      };
      
      // in the same header..
      
      void DoOtherThings () // declaration
      {
          // the function's code (definition) goes here
      }
      

      在任何情况下,没有强保证,即使您使用编译器特定的关键字进行内联强制也是如此。

      100% 的保证是将您的函数转换为 C++ 宏并使用该宏而不是引用该函数。如果您的函数有多行,请在“宏函数”中要换行的位置放置 \(空格后跟反斜杠)。

      【讨论】:

      • 通过将函数的定义直接放入头文件中的声明”除了使inline之外还有什么意思?
      • @JonathanWakely 更新了答案以说明其含义。
      猜你喜欢
      • 2019-03-08
      • 2017-01-05
      • 1970-01-01
      • 2011-01-24
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多