【问题标题】:Preventing gcc from inlining a function [duplicate]防止gcc内联函数[重复]
【发布时间】:2011-11-02 11:26:45
【问题描述】:

是否可以防止 gcc 编译器内联特定函数。如果是这样,怎么做?

不要告诉我降低优化级别。我希望进行所有优化,但将特定函数标记为不被编译器内联,就像变量的情况下的 volatile 一样。

我想这样做的原因是因为我的函数使用内联汇编定义的标签,当它内联函数时 gcc 搞砸了,因为内联会导致 gcc 创建该标签的多个实例。

【问题讨论】:

  • 请更准确地解释您的问题。标签的多个实例?这不应该发生。哪个版本的 gcc 给了你这个?你确定你只在一个单一的编译单元中定义了函数?
  • @Jens,发生这种情况的原因是内联函数直接放在代码中,所以如果你在该函数中有一个内联汇编定义的标签,编译器也会在它插入代码的任何地方复制它对于那个内联函数。
  • 请注意,您实际上不需要阻止内联来解决此问题;您可以简单地使用匿名相对标签 (0,...,9)。
  • 防止内联一些重要到足以包含汇编的东西有一些严重的代码气味。听起来你正在做的事情需要重新考虑。这可能确实是唯一的方法,但那肯定是极不可能的情况......
  • @MetallicPriest,所以你问错了问题。对您来说有趣的是拥有不需要绝对标签的流量控制。由于 gcc 似乎确信您的代码非常小(否则它不会内联),这不能太复杂。

标签: c linux gcc x86


【解决方案1】:

您应该使用noinline 属性

像这样:

void the_method_you_dont_want_to_inline() __attribute__ ((noinline))
{
  ...
}

或在最新版本的 GCC 中:

__attribute__((noinline)) void the_method_you_dont_want_to_inline()
{
  ...
}

【讨论】:

  • 我试过了,但编译器说函数定义中不允许有属性
  • @MetallicPriest :我编辑了我的答案,并针对最新版本的 gcc 进行了更正
【解决方案2】:
void foo() __attribute__ ((noinline)) { }

【讨论】:

  • 我试过了,但编译器说函数定义中不允许使用属性。
【解决方案3】:

您必须将参数__attribute__((noinline)) 设置为函数。

这看起来像这样:

void __attribute__((noinline)) MyFunction(void)
{
    printf("This will never be inlined");
}

【讨论】:

    【解决方案4】:

    __attribute__(noinline) 是您将要获得的收盘价。

    【讨论】:

    • 编译器说,错误:函数定义中不允许使用属性
    • 查看您的问题重复。
    【解决方案5】:

    __attribute__(noinline) 应该放在第一位,如下图所示。否则编译器会抱怨函数定义中不允许使用属性。

    __attribute__(noinline) void my_function( void * arg )
    {
      .....
    }
    

    【讨论】:

      【解决方案6】:

      另一种方法是给声明的属性,而不是函数的定义;例如

      static void foo() __attribute__ ((noinline));
      

      以后

      static void foo() {
      //code here
      }
      

      但也许您仍然可以通过在其中使用 local labels__label__ 来内联函数,类似于

      static void inline foo() {
         // untested!
         __label__ foo;
        foo:
          asm ("do something tricky");
          goto foo;
      }
      

      但是MetallicPriest,你应该提供更多的细节,或许可以展示更多你的代码和目标,以获得更好的帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-18
        • 2011-04-13
        • 1970-01-01
        相关资源
        最近更新 更多