2009-07-30 39 views
9

我知道你可以使用inline关键字,或者只是在类声明ala short ctor或getter方法中放置一个方法,但是编译器会在什么时候内联我的方法做出最终决定?编译器是否决定何时内联函数(使用C++)?

例如:

inline void Foo::vLongBar() 
{ 
    //several function calls and lines of code 
} 

将编译器忽略,如果它认为它会让我的代码效率低下我的inline声明?

作为一个方面的问题,如果我宣布我的课之外的getter方法是这样的:

void Foo::bar() { std::cout << "baz"; } 

请问在幕后编译器内联呢?

回答

9

无论是否fiunction是内联就是,在一天结束的时候,完全编译器最多可达 。通常,函数在流程方面越复杂,编译器将其内联的可能性就越小。并且一些函数(如递归函数)不能被内联。

不内联函数的主要原因是它会大大增加代码的总体大小,防止Iot被保存在处理器的缓存中。这实际上是一种悲观,而不是一种优化。对于让程序员决定自己在脚下或其他地方自己拍摄,你可以自己内联函数 - 编写在本函数的调用位置处已经进入函数的代码。

+0

请看我对JaredPar的回答的评论。 – jkeys 2009-07-30 07:32:11

15

是的,内联代码的最终决定在于C++编译器。 inline关键字是一个建议,而不是要求。

这里有一些细节,如何这决定在Microsoft C++处理编译

+1

你能详细说明这是为什么吗?我认为C++的意义在于给程序员足够的绳索来挂断自己,但这似乎是限制性的。有没有很好的理由? – jkeys 2009-07-30 07:31:27

+1

@Hooked,看看我发布的链接。它详细介绍了为什么这不总是一件好事。我想到的第一件事是头递归函数。 – JaredPar 2009-07-30 07:32:13

+1

该标准规定,即使__forceinline没有结束辩论,编译器仍然有最后一句话。我可以理解什么时候内联会是不合适的,但是如果一个程序员/分析人员决定超编译器,他有什么选择?该链接没有详细说明让编译器决定的理由。 – jkeys 2009-07-30 07:37:00

1

据我所知,编译器会自动生成一个函数,如果它发现了一个类似for的循环,它会自动生成一个内联函数(或者在类声明中写入)的非内联函数。 这是编译器最后一个例子在内联函数中说。

4

正如许多已经公布,最终决定始终是编译器,即使你可以给公司的提示,如forceinline。
基本原理的一部分是内联不是一个自动“更快”的开关。内联过多会使您的代码变得更大,并且可能会干扰其他优化。见The C++ FAQ Lite about inline functions and performance

2

作为一个方面的问题,如果我宣布一个getter方法我班外面是这样的:

void Foo::bar() { std::cout << "baz"; } 

请问在幕后编译器内联呢?

这取决于。它可以用于同一翻译单元中的所有呼叫者(.cpp文件及其所有#included定义)。但它仍然需要编译一个非内联版本,因为在翻译单元之外可能会有该函数的调用者。您可以在高优化级别上看到这一点(如果您的编译器实际上可以实现这一点)。 (尤其是:比较将#include所有.cpp文件中的所有.cpp文件与典型布局进行比较。在一个翻译单元中的所有定义都会显着增加这种内联的机会。)

3

正如其他人注意到的,inline关键字仅仅是对编译器内联代码的一种建议。由于编译器会经常内嵌没有标记为inline的代码,而不是内联代码,所以关键字看起来与register或(pre-C++ 0x)auto一样多余。

然而,有一件事是,inline关键字效果:它改变了从外部(默认为功能)功能的联动在线。内联链接允许每个编译单元包含它自己的目标代码副本,并且链接器从最终的可执行文件中删除多余的副本。如果这提醒你模板,是的,模板也使用内联链接。

3

我想补充我5毛钱......

我发现这个Guru of Week文章关于内联非常有用的。

据我所知,我在某处甚至连链接器都可能做内联,当它链接对象文件并发现被链接的代码可以内联。

问候,
Ovanes

1

如果你真的肯定,绝对没有失败NEED内联代码,总有宏。 C多年来一直支持这些技术,并且因为它们在编译之前只是文本替换,所以它们确实真实地嵌入了您所写的任何内容。

这就是为什么'inline'关键字(甚至在某些情况下是强制变体)可以承受没有强制它的标准方式 - 你总是可以写一个宏。

也就是说,inline关键字通常更好,因为编译器经常知道是否使内联函数有意义,并且因为内联可以与编译器优化的其余部分进行交互。

相关问题