RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 949119
Accepted
Stanislav Petrov
Stanislav Petrov
Asked:2020-02-25 17:51:55 +0000 UTC2020-02-25 17:51:55 +0000 UTC 2020-02-25 17:51:55 +0000 UTC

为什么包含循环、递归或被指针调用的函数极易发生内联(inline)

  • 772

为什么包含循环、递归或被指针调用的函数极易发生内联(inline)

c++
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    AnT stands with Russia
    2020-02-26T01:14:30Z2020-02-26T01:14:30Z

    这个问题是基于术语混淆。函数调用内联不是函数本身的属性,而始终是单个函数调用的属性。当然,函数本身的属性在决定是否内联特定调用方面发挥作用,但在一般情况下,这个决定仍然是根据具体情况做出的。一些函数调用可能是内联的,而对同一函数的其他调用可能不是内联的。甚至在特定调用中指定的函数参数也会影响是否内联该特定调用的决定。

    • 没有内联循环函数调用的声明属于“很久以前并且不是真的”类别。

      每个编译器都实现了一些启发式方法,使其能够就对给定函数的调用是否值得内联做出一般决定。在其中一个旧编译器中,这种启发式方法还包括检查函数体的循环(Borland 或类似的东西)。

      事实上,循环并不代表嵌入的任何障碍。我不知道有任何现代实现拒绝内联带有循环的函数调用。

    • 通过指针调用的函数没有内联的声明只是我在上面写的术语混淆的一个生动例子。通常不内联的是通过指针进行的调用。同时,直接调用同一个函数也可以内联。

      为什么通常不可能内联通过指针进行的调用是显而易见的:因为在编译时并不清楚将调用哪个函数。但是,如果编译器能够在编译时确定将通过指针调用哪个函数,它也很容易内联这样的调用。

      基于这种术语混淆的经典常见问题是内联类虚拟方法调用的问题。毕竟,它们被称为“通过指针”,因此不能内置,对吧?不对。首先,用户自己可以直接进行虚方法调用,无需使用虚机制。其次,在大量上下文中,编译器本身能够确定在给定调用中调用了哪个特定方法,并因此内联该调用。

    • 递归函数调用也可以内联。如果编译器能够在编译时估计递归的最大深度,那么它可以将这些调用(“扩展递归”)内联到其全部深度。如果编译器无法进行这样的评估,那么它可以将递归调用内联到某个固定深度,然后执行常规递归调用。在这方面,内联递归函数调用很像展开循环。

    嵌入函数调用的最简单和最明显的情况之一是,例如,已知某个函数在程序中只被调用一次的情况(在空间意义上,即程序源代码它的调用只包含一个地方)。没有理由让这样的函数作为一个单独的函数存在,不管这个函数有多“重”。(这里有许多附带警告,但它们与本主题无关。)例如,如果一个函数是内部绑定的并且在其翻译单元中只调用一次,那么现代编译器将内联该调用而不管任何其他标准。在 GCC 编译器中,一个选项对此负责,该选项-finline-functions-called-once已在 mode 中启用-O1。

    作为另一个示例,MSVC++ 编译器具有控制递归函数的内联和递归扫描深度的选项#pragma。inline_recursioninline_depth

    • 13
  2. Harry
    2020-02-25T17:58:13Z2020-02-25T17:58:13Z

    好吧,递归很清楚——如果它没有被编译器转换成循环,那么会发生什么?我们嵌入代码,在它调用的地方我们再次嵌入代码,在调用的地方......我们应该嵌入多少次代码?:)

    通过指针调用 - 再次:如果是内置的,则该函数没有明确的序言 - 结尾,并且不能通过地址调用 - 所以当通过指针调用时,必须有一个非内置实例至少该功能 - 以便有一些东西可以调用。

    在调用的地方,不能通过指针嵌入任何内容 - 因为编译器嵌入,并且在编译时指针的值是未知的。

    关于周期-在我看来,您在这里混淆了一些东西。内部带有循环的函数是非常可嵌入的——当然,如果它有意义:) 如果你的意思是循环本身是未展开的——那么再次,这已经完成,但有其自身的限制——例如,编译器可能不会知道实际上将完成多少次迭代 - 那么他如何展开循环?..

    • 12

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5