定义一个调用其他函数的内联函数是否有意义?

时间:2015-01-12 14:27:08

标签: c++ inline

据我所知,内联函数是一种优化以提高性能,因此它应该像宏一样快速运行。内联函数的代码应尽可能短。

我想知道在内联函数中嵌入函数调用是否有意义。如果答案是肯定的,那么在哪种情况下有什么限制?

实际上,我问这个问题是因为我查看了一个调用函数的代码,例如" socket()"," sendto()"和" memset()"来自内联函数;在我看来,这些内容超越了内联函数的用途。

注意:在我的代码中没有使用对函数的任何条件调用,内联函数只是将参数传递给被调用的函数。

6 个答案:

答案 0 :(得分:3)

  

我想知道在内联函数中嵌入函数调用是否有意义。

当然可以。内联对函数的调用仍然是一种优化,消除了该函数调用的成本,并允许在调用函数的上下文中进一步优化,无论它是否依次调用其他函数。

  

在哪种情况下有什么限制?

我不知道你的意思" context&#34 ;;但是对内联函数的功能没有限制。声明函数inline的唯一语义效果是允许多个相同的定义,并且需要在使用该函数的任何转换单元中定义。在所有其他方面,它与任何其他功能定义相同。

答案 1 :(得分:2)

我没有看到为什么内联代码不能包含函数调用的先验原因。

参数传递放弃,内联插入代码行,减少调用开销并允许本地/临时优化。

例如,使用inline void MyInline(bool Perform) { if (Perform) memset(); }调用时,很可能会跳过MyInline(false)

内联还可以允许内部函数调用的内联,从而产生更多(微)优化机会。

答案 2 :(得分:2)

评论根据要求发布为答案:

如果编写代码的人认为inline对性能有任何有意义的影响,那么他显然不会做正确的事情。'。

性能来自正确的算法选择和避免缓存未命中。

头痛来自可能在1991年起作用的天真的早熟优化技术

答案 3 :(得分:1)

编译器将选择何时内联。并且您应该避免尝试过早优化,而不是暴露您的实现。

编译器可能能够优化您正在调用的函数的转发。无论如何,即使您不使用内联关键字,也可以使用优化标记。

使用inline关键字的时间是指您想要在多个项目中使用仅标题文件而不必使用链接库。实际上,这并不意味着“内联”,它意味着“只有一个定义”,即使是在调用函数的编译单元中也是如此。

无论如何你应该看看这个维基问题/答案:

Benefits of inline functions in C++?

答案 4 :(得分:1)

它非常有意义。

考虑一个由两个可能的执行分支组成的函数 - 一个快速路径,当某些条件成立时(大部分时间)和慢速路径被激活。

内联整个内容会导致代码的大小增加,效果不大。缓慢的路径复杂性可能会阻止编译器内联函数。

如果您将慢速路径变为单独的功能,则会打开一个有趣的机会。

当慢速路径仍然是函数调用时,它可以内联条件和快速路径。内联快速路径允许在大多数时间避免函数调用开销。慢速路径已经很慢,因此呼叫开销可以忽略不计。

答案 5 :(得分:0)

首先,在C ++中,"内联"函数(在头文件中声明或标记为这样的函数)只是对编译器的建议。编译器本身将决定是否实际内联。

内联函数有三个原因:

  1. 将另一轮变量推入堆栈是非常昂贵的,分支到程序中的新点。
  2. 有时我们可以使用函数的中间体进行局部优化(虽然我不会指望它!)
  3. 将函数的定义放在头文件中(解决)。
  4. 采取以下示例

    void NonInlinable(int x);
    inline void Inline() { NonInlinable(10);}
    

    这对内联有很大的意义。我删除了1个函数调用,所以如果NonInlinable相当快,那么这可能是一个巨大的加速。所以不管我是否正在调用函数,我仍然想要内联调用。

    另一个例子:

     inline int Inline(int y) {return y/10;}
     //main
     ...
     int x = 5;
     int y = Inline(5);
     int z = x % 10;
    

    模数和设计操作通常由同一指令计算。一个非常好的编译器,可以在1个汇编指令中计算y和z! 魔术

    所以在我看来,一个更好的问题是我何时使用内联函数:

    1. 当我想将定义与声明分开时(非常好的可读性实践,过早的优化是所有邪恶的根源)。
    2. 当我想隐藏我的实现/使用良好的封装时。