题
如果我定义的一个非成员能在一个标题,将它始终可通过内联编译器,或者没有编译器选择根据其启发?我知道,__内联仅仅是一个提示,这是同职能的标题?
解决方案
请记住,包括从头部的东西不大于只是直接在源文件中键入它不同。因此,在一个头是没有什么区别,只要编译器而言;它从不知道它在那里。
所以,当你定义在头文件中的函数,并且您在一个文件中的头文件,它就像你刚才输入的功能,直入文件。所以,现在的问题是,“该编译器选择基于启发式内嵌的东西呢?”
答案是“这取决于编译器”。该标准使什么被内联或没有任何保证。这就是说,任何现代编译器将是什么它内联,有可能与启发式聪明绝顶。
但是,我们来到一个有趣的问题。想象一下,你有一个头的功能与您在多个源文件头。然后,您将有功能的多个定义,跨翻译单元,而这违反了一个定义规则。人机工程学,你会得到编译错误。 (链接器错误通常是沿着线的东西:“错误,函数Y X已经定义”)。你可以做的是使用inline
关键字,你不再违反ODR
顺便说__inline
是非标准的。相反,您的文章,它通常是一个编译器的扩展,它的力量的内联,而不是暗示它。 inline
是标准的关键字,它最初是为了暗示了内联。像你说的,最现代的编译器完全忽略它在这方面,它的唯一目的时下是给事物内部链接。
其他提示
从 C ++ FAQ精简版 :
不管你如何指定功能 为内联,这是一个要求,即 编译器允许忽略:它 可能直列扩大一些,全部或没有 的呼叫到一个内联函数。
它将选择基于启发式方法。确保你把它声明为内联明确,否则你可能会得到一个重复的符号链接错误如果您在多个编译单元的标题。
如果您的确定的与在头文件外部链接的功能,并将其包含到一个以上的翻译单元,你会得到编译错误(更精确地连接erorr)违反一个定义的规则(ODR)。因此,答案是“不”:定义在头文件中的功能将无法在内嵌采取编译器作为一个提示,并不会从观察ODR的要求为你开脱。不仅如此功能并不能保证被内联,但最有可能你的程序甚至不会编译。
为了在头文件中定义的函数,并且逃脱它你必须要么给它的内部连接(声明它static
,并在每个转换单元单独的函数结束),或明确地声明它inline
。
作为用于启发式...现代编译器通常会考虑内联(通过施加启发式)的几乎任何函数,无论它被定义,其中,以及它是否被显式声明inline
与否。
没有魔法的有关职能的标题。编译器甚至不知道是否有一个功能的定义是在一个标题或者没有。(因为标题有效地复制/粘贴到的源文件,可以定义,它在一个标题,但编译器只是把它看作一部分的翻译单位)
还有两个不同的含义的"内联"以注意:
功能可以 内联 如定义通过的C++标准:这样做是通过之前加上功能 inline
关键词,或者如果它是一个成员的功能,通过确定它在地方内部的类定义。
效果是
- 通知的接头,它可能会遇到的功能定义在多个文件,它应该只是默默地将它们合并在一起,而不是扔一个错误
- 使它更容易编译器,来执行内联 优化.
该内联 优化 另一方面,只是该法的更换呼叫功能的身的所谓的功能,这意味着这种优化为实际应用到电话网站,不要功能。功能可以被称为通常一些地方,但是内联其他地方。呼叫功能是内联时,编译器的感觉,这最好是在概念上单独完全从第一意义的"内联".
编译器将适用优化内联否、何时和在哪里感觉就像它。它大量采用了启发式的。小功能的更可能是内联。如果确定某个特定电话网站将是执行,足够经常的,这是更可能是内联。最终,试探它使用的是基于"将它提高或降低性能"。和它一般是更好地判断这于人类的,所以你应该不是真的需要知道什么精确的启发,它使用。内联太多只会损害的性能。