C++内联函数?

Posted

技术标签:

【中文标题】C++内联函数?【英文标题】:c++ inline function? 【发布时间】:2011-08-23 17:24:21 【问题描述】:

我为什么要这样做:

inline double square (double x)  return x*x;

而不是

double square (double x)  return x*x;

有区别吗?

【问题讨论】:

Inline functions vs Preprocessor macros 的可能重复项 其实有很多骗子和近乎骗子:***.com/search?q=c%2B%2B+inline。有些答案比其他答案更好,其中一些错误地指出inline 关键字导致函数在所有调用站点内联,等等。这可能不是最接近的骗局。 另请参阅 C++ 常见问题解答中的 Inline Functions。他们对内联有很好的处理。 【参考方案1】:

前者(使用inline)允许您将该函数放在一个头文件中,它可以包含在多个源文件中。使用inline 使标识符在文件范围 中,很像声明它static。如果不使用inline,您会从链接器中得到一个多符号定义错误。

当然,这是对编译器的提示,即应该将函数内联编译到使用它的位置(避免函数调用开销)。编译器不需要对inline 提示进行操作。

【讨论】:

我认为内联的目的是让编译器'扩展'调用它的函数的内容,所以不会有vtable查找(或指令跳转到CPU上的函数级别)。 你的第一点是预期目的的[有用]副作用吗? @Ian Fleeton:确实是副作用;如果内联标识符没有文件范围,那么根本不可能将内联函数定义放在头文件中。 @Greg:它不像static。如果是这样,每个翻译单元将对它的函数副本拥有自己的所有权,并且链接器会将它们全部视为不同的函数(恰好具有相同的名称)。相反,inline 指示链接器,如果它看到此函数的不同定义,它们都是相同的,必须合并为一个。但是忽略这个细节,它在大多数情况下确实表现得好像是static @DJ:inline 无法阻止 vtable 查找,您需要为此调用去虚拟化【参考方案2】:

在现代编译器上可能没有太大区别。它可能在没有inline 的情况下被内联,它可能被内联 inline

【讨论】:

有道理,我从参考和 10 年的经验出发。【参考方案3】:

是的,有区别。 https://isocpp.org/wiki/faq/inline-functions.

当您指定一个函数是内联的时,您会导致编译器将该方法的代码放在任何被调用的地方。

void myfunc() 
  square(2);

等同于

void myfunc() 
   2 * 2;

调用函数有利于代码清晰,但是当调用该函数时,必须将本地状态推入堆栈,为该方法设置一个新的本地状态,完成后需要返回之前的状态弹出。这是很多开销。

现在,如果您提高优化级别,编译器将做出诸如展开循环或内联函数之类的决定。编译器仍然可以随意忽略内联语句。

【讨论】:

我认为使用 gcc 您可以使用编译标志 -Winline 在函数不会被内联时发出警告。如果您是一名受虐狂,您可以将其与 -Werror 结合使用。 "编译器仍然可以忽略内联语句。"事实上,每个现代编译器都这样做。【参考方案4】:

来自 Wikipedia:内联函数是要求编译器执行内联扩展的函数。换句话说,程序员要求编译器在每个调用函数的地方插入完整的函数体,而不是在定义的地方生成代码来调用函数。编译器没有义务尊重这一要求。

http://en.wikipedia.org/wiki/Inline_function

【讨论】:

【参考方案5】:

inline过程抽象的概念配合得很好

inline double square (double x)  return x*x;

int squareTwice(double x) 
    double first = square(x);
    double second = square(x);
    return first * second; 

上面与下面基本相似:

int squareTwice(double x) 
    double first = x*x;
    double second = x*x;
    return first * second; 

这是因为当编译器内联扩展函数调用时,函数的代码被插入到调用者的代码流中;因此,在程序上将第二个示例抽象为第一个示例可能更容易。

过程抽象可以将例程分解为更易于阅读的较小子例程(尽管这可以是一种风格选择)。

【讨论】:

【参考方案6】:

如果编译器符合要求,内联函数将在调用它的代码中包含内联函数,就好像没有调用任何函数一样(就好像您已将逻辑放在调用函数中一样)并避免函数调用开销.

【讨论】:

编译器如果不想内联函数也不必内联,即使指定了 inline 关键字。 @Alex Marlon 没有说编译器不会内联函数,只是说它不必。这些是非常不同的事情。

以上是关于C++内联函数?的主要内容,如果未能解决你的问题,请参考以下文章

何时可以/将在 C++ 中内联函数?可以强制内联行为吗?

C++基础语法梳理:inline 内联函数!虚函数可以是内联函数吗?

复习笔记——C++内联函数

c++中的内联函数inline

C++基础--inline

内联函数和宏