代码之家  ›  专栏  ›  技术社区  ›  Rob

内联C++代码

  •  9
  • Rob  · 技术社区  · 16 年前

    以下代码有什么不同吗?

    class Foo  
    {
      inline int SomeFunc() { return 42; }
      int AnotherFunc() { return 42; }
    };
    

    两个函数都是内联的吗?内联实际上有什么区别吗?什么时候应该或不应该内联代码有什么规则吗?我经常使用 AnotherFunc 语法(例如访问器),但我很少指定 inline 直接。

    9 回复  |  直到 16 年前
        1
  •  16
  •   Branan    16 年前

    两种形式的内联方式应该完全相同。inline对于类定义中定义的函数体是隐式的。

        2
  •  26
  •   Greg Hewgill    16 年前

    这个 inline 关键字本质上是编译器的提示。使用 内联的 不能保证你的功能 是内联的,省略它也不能保证它 不会 . 您只是让编译器知道,更努力地内联该特定函数可能是一个好主意。

        3
  •  6
  •   Nemanja Trifunovic    16 年前

    萨特的本周大师33回答了你的一些问题和更多。

    http://www.gotw.ca/gotw/033.htm

        4
  •  3
  •   unwieldy    16 年前
    class Foo  
    {
      inline int SomeFunc() { return 42; }
      int AnotherFunc() { return 42; }
    };
    

    正确的是,两种方法都保证编译相同的代码。然而,最好不要这样做。根据 the C++ FAQ 您应该在类定义内正常地声明它,然后在类定义外、在头中使用显式 内联的 关键字。正如常见问题解答所描述的,这是因为您希望将声明和定义分开,以便于其他人阅读(声明等同于“什么”和“如何”的定义)。

    内联实际上有什么区别吗?

    是的,如果编译器授予内联请求,它就大不相同了。把内联代码看作一个宏。在调用它的任何地方,函数调用都将替换为函数定义中的实际代码。如果您内联大型函数,这可能会导致代码膨胀,但是编译器通常通过在函数太大时不授予内联请求来保护您不受此影响。

    什么时候应该或不应该内联代码有什么规则吗?

    我不知道任何硬+快的规则,但是一个准则是,如果经常调用内联代码,并且它相对较小,那么它只能是内联代码。setter和getter通常是内联的。如果它在代码的一个特别高性能的领域中,那么应该考虑内联。请记住,您是在用内联来交换可执行大小的执行速度。

        5
  •  2
  •   Rob Walker    16 年前

    VC++支持 __forceinline __declspec(noinline) 如果您认为自己比编译器更了解指令。提示:你可能不会!

        6
  •  2
  •   Mike    16 年前

    内联是编译器提示,不强制编译器对代码进行内联(至少在C++中)。因此,简短的答案是它是编译器,并且可能取决于上下文,在您的示例中会发生什么。大多数优秀的编译器可能会同时内联这两个函数,特别是由于对两个函数的常量返回进行了明显的优化。

    一般来说,内联不是您应该担心的事情。它带来了不必执行机器指令来生成堆栈帧和返回控制流的性能优势。但除了最专业的案例,我认为这是微不足道的。

    内联在两种情况下很重要。如果你在一个实时的环境中,响应速度不够快。第二个问题是,如果代码分析在一个非常紧密的循环(即一个被反复调用的子程序)中显示了一个明显的瓶颈,那么内联可能会有所帮助。

    特定的应用程序和体系结构也可能导致您将内联作为优化。

        7
  •  1
  •   Roger Nelson    16 年前

    我发现一些C++编译器(即SunStudio)抱怨如果省略了内联,那么

    int AnotherFunc() { return 42; }
    

    所以我建议在这种情况下始终使用inline关键字。不要忘记删除内联关键字,如果你以后将该方法实现为一个实际函数调用,这将真的搞乱链接(在SunStudio 11和12和Borland C++ + Builder)中。 我建议尽量少使用内联代码,因为当使用调试器单步执行代码时,它将“单步执行”内联代码,即使使用“单步执行”命令,这也会非常烦人。

        8
  •  0
  •   Tim James    16 年前

    注意,在课堂之外, inline 在代码中做一些更有用的事情:通过强制(很好地)C++编译器在每次调用函数时生成内联代码,它防止在不同的翻译单元中对同一符号(函数签名)的多个定义。

    因此,如果您在头文件中嵌入一个非成员函数,并将其包含在多个cpp文件中,那么链接器就不会对您大喊大叫。如果函数太大,无法建议内联,请按C方式执行:在头中声明,在cpp中定义。

    这与代码是否真正是内联的关系不大:它允许在头中实现样式,这对于短成员函数很常见。

    (我认为,如果编译器需要非内联的函数呈现,就像模板函数一样,它将是智能的,但是…)

        9
  •  0
  •   RomanM    16 年前

    在执行优化(即 inline -编译器不仅查询代码中的关键字,还查询其他命令行参数,指定编译器应如何优化代码。