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++内联函数?的主要内容,如果未能解决你的问题,请参考以下文章