我知道内联是对编译器的提示或请求,用于避免函数调用开销。

那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?


当前回答

我经常使用内联函数不是为了优化,而是为了使代码更具可读性。有时代码本身比注释、描述性名称等更短、更容易理解。例如:

void IncreaseCount() { freeInstancesCnt++; }

读者可以立即了解代码的完整语义。

其他回答

最好的方法是检查和比较生成的内联和非内联指令。但是,省略内联总是安全的。使用内联可能会导致您不想要的麻烦。

避免函数调用的开销只是故事的一半。

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中定义的内联函数的其他规则仍应遵守。

我读了一些答案,发现有些东西缺失了。

我使用的规则是不使用内联,除非我希望它是内联的。看起来很傻,现在解释一下。

编译器足够聪明,短函数总是内联的。永远不要让长函数作为内联函数,除非程序员说这样做。

我知道内联是一个提示或请求编译器

实际上,内联是编译器的一个命令,它没有选择,并且在内联关键字之后使所有代码内联。所以你永远不能使用内联关键字和编译器将设计最短的代码。

那么什么时候使用内联呢?

如果您想内联一些代码,则使用。我只知道一个例子,因为我只在一种情况下使用它。即用户认证。

例如,我有这样一个函数:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

不管这个函数有多大,我都想把它作为内联的,因为它使我的软件更难破解。

此外,在维护大型项目时,内联方法有严重的副作用。当内联代码被更改时,所有使用它的文件将由编译器自动重建(如果它是一个好的编译器)。这可能会浪费大量的开发时间。

当内联方法被传输到源文件而不再内联时,整个项目必须重新构建(至少这是我的经验)。当方法转换为内联时也是如此。

我经常使用内联函数不是为了优化,而是为了使代码更具可读性。有时代码本身比注释、描述性名称等更短、更容易理解。例如:

void IncreaseCount() { freeInstancesCnt++; }

读者可以立即了解代码的完整语义。