【问题标题】:compiler limitations, when inlining a function内联函数时的编译器限制
【发布时间】:2013-08-16 15:48:29
【问题描述】:

我知道在类成员函数中添加 inline 关键字后,如果“函数不复杂”或者函数体中有“很多语句”,编译器会决定内联。

  1. 什么被认为是“很多陈述”?

  2. 如果函数的地址被隐式或显式获取,编译器也无法执行内联。谁能解释一下这一点?

  3. 因为内联只是一个建议,我该如何测试哪些函数没有内联?

【问题讨论】:

    标签: c++ inline


    【解决方案1】:
    1. 这完全取决于编译器;这可能取决于优化设置、目标架构的特性(例如,函数调用的成本与由于代码大小增加而导致的缓存未命中的潜在成本)以及函数与其余代码的集成程度在特定的呼叫站点。

    2. 1234563出于这个原因,这样的函数不再有地址,因为它与调用者混合在一起。但是,当您请求函数地址时,通常会发生的情况是,编译器会在它最喜欢的地方内联函数,但仍将它作为“常规函数”发出,并通过函数指针使用其地址.
    3. 您可以反汇编生成的可执行文件,或要求编译器发出程序集而不是构建完成的可执行文件(使用gcc 这是-S 选项)并手动检查它。尽管如此,请注意检查优化的二进制文件并非易事——因为内联代码与调用者代码混合在一起,可能很难准确地找出内联函数的去向,同时您也可能会在非内联的副本中找到通过函数指针使用函数(如上所述)。

    【讨论】:

      【解决方案2】:
      1. 编译器是否生成内联代码取决于 编译器。大多数现代编译器会生成很多 任何不是递归内联的东西。

      2. 这完全是错误的。获取地址后, 编译器必须为地址生成一个行外副本,但是 这并不能阻止它在函数运行时内联 调用。

      3. 你没有。

      【讨论】:

        【解决方案3】:
        1. 完全由编译器设计者决定使用什么启发式方法来决定是否内联函数调用。希望它基于生成的代码大小而不是“语句”的数量,这是一个完全没有意义的指标。希望它还包括对性能增益的估计,以权衡代码大小的任何增加。

        2. 如果地址被占用,那么必须有一个函数的非内联实例,以便获取地址。但是,这不会阻止对函数的任何调用被内联,如果编译器决定它们应该被内联。

        3. 你可以反汇编生成的代码,看看是否有函数调用。如果调用函数很大,或者它本身内联在另一个函数中,这可能会很棘手。大多数编译器都有一种(非标准的)强制内联方式;但只有在您确定自己比编译器更了解并有测量结果证明这一点时才使用它。

        【讨论】:

          【解决方案4】:

          关于编译器何时内联的问题,请查看此线程:

          Does the compiler decide when to inline my functions (in C++)?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-12-09
            • 1970-01-01
            • 2015-01-10
            • 1970-01-01
            • 2020-06-23
            • 2011-01-25
            • 1970-01-01
            • 2010-10-13
            相关资源
            最近更新 更多