我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
当前回答
避免函数调用的开销只是故事的一半。
do:
使用inline代替#define 非常小的函数适合内联:更快的代码和更小的可执行文件(更多的机会留在代码缓存中) 这个函数很小,并且经常被调用
别:
large functions: leads to larger executables, which significantly impairs performance regardless of the faster execution that results from the calling overhead inline functions that are I/O bound the function is seldom used constructors and destructors: even when empty, the compiler generates code for them breaking binary compatibility when developing libraries: inline an existing function change an inline function or make an inline function non-inline: prior version of the library call the old implementation
在开发一个库的时候,为了让一个类将来可以扩展,你应该:
即使主体为空,也要添加非内联虚析构函数 使所有构造函数都是非内联的 除非类不能按值复制,否则编写复制构造函数和赋值操作符的非内联实现
记住,inline关键字是给编译器的一个提示:编译器可能决定不内联某个函数,也可能决定内联那些一开始就没有标记为内联的函数。我通常避免将函数标记为内联(可能在编写非常非常小的函数时分开)。
关于性能,明智的方法(一如既往)是分析应用程序,然后最终内联一组表示瓶颈的函数。
引用:
内联还是不内联 [9]内联函数 c++的策略/二进制兼容性问题 GotW #33:内联 内联回来的 有效的c++ -项目33:明智地使用内联
编辑:Bjarne Stroustrup, c++编程语言:
函数可以定义为内联的。例如:
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
The inline specifier is a hint to the compiler that it should attempt to generate code for a call of fac() inline rather than laying down the code for the function once and then calling through the usual function call mechanism. A clever compiler can generate the constant 720 for a call fac(6). The possibility of mutually recursive inline functions, inline functions that recurse or not depending on input, etc., makes it impossible to guarantee that every call of an inline function is actually inlined. The degree of cleverness of a compiler cannot be legislated, so one compiler might generate 720, another 6 * fac(5), and yet another an un-inlined call fac(6). To make inlining possible in the absence of unusually clever compilation and linking facilities, the definition–and not just the declaration–of an inline function must be in scope (§9.2). An inline especifier does not affect the semantics of a function. In particular, an inline function still has a unique address and so has static variables (§7.1.2) of an inline function.
EDIT2: ISO-IEC 14882-1998, 7.1.2功能说明
使用内联说明符的函数声明(8.3.5,9.3,11.4)声明了一个内联函数。内联说明符向实现指示,在调用点对函数体进行内联替换将优先于通常的函数调用机制。实现不需要在调用点执行这种内联替换;然而,即使省略了这个内联替换,7.1.2中定义的内联函数的其他规则仍应遵守。
其他回答
当你认为你的代码足够小,可以作为内联使用,记住内联函数复制你的代码,并在函数被调用时粘贴它,这样可能会增加你的执行时间,但也会增加内存消耗。 当你使用循环/静态变量/递归/切换/goto/虚函数时,你不能使用内联函数。 虚的意思是等到运行时,内联的意思是在编译期间,所以它们不能同时使用。
我通常遵循一个拇指规则,我用3-4个简单的语句作为内联函数。但最好记住,这只是给编译器的一个提示。最终是否使它内联的调用仅由编译器执行。如果有超过这些语句,我不会用一个愚蠢的编译器进行内联声明,这可能会导致代码膨胀。
我读了一些答案,发现有些东西缺失了。
我使用的规则是不使用内联,除非我希望它是内联的。看起来很傻,现在解释一下。
编译器足够聪明,短函数总是内联的。永远不要让长函数作为内联函数,除非程序员说这样做。
我知道内联是一个提示或请求编译器
实际上,内联是编译器的一个命令,它没有选择,并且在内联关键字之后使所有代码内联。所以你永远不能使用内联关键字和编译器将设计最短的代码。
那么什么时候使用内联呢?
如果您想内联一些代码,则使用。我只知道一个例子,因为我只在一种情况下使用它。即用户认证。
例如,我有这样一个函数:
inline bool ValidUser(const std::string& username, const std::string& password)
{
//here it is quite long function
}
不管这个函数有多大,我都想把它作为内联的,因为它使我的软件更难破解。
内联与优化关系很小。内联是给编译器的指令,如果给定的函数定义在程序中多次出现,则不会产生错误,并承诺该定义将出现在使用它的每次翻译中,并且在出现它的任何地方都具有完全相同的定义。
根据上述规则,内联适用于短函数,其函数体不需要包含超出声明所需的额外依赖项。每次遇到定义时,都必须对其进行解析,并可能生成其主体的代码,因此对于在单个源文件中只定义一次的函数,这意味着一些编译器开销。
编译器可以内联(即用执行该函数操作的代码替换对函数的调用)它选择的任何函数调用。过去的情况是,它“显然”不能内联一个没有在同一个翻译单元中声明的函数,但随着链接时间优化的使用越来越多,现在这种情况也不存在了。同样正确的是,标记为内联的函数可能不是内联的。
内联函数可以通过消除将参数推入堆栈的需要来提高代码性能。 如果有问题的函数在你的代码的关键部分,你应该在项目的优化部分做出内联而不是内联的决定,
你可以在c++ FAQ中阅读更多关于内联的内容