什么时候使用内联函数,什么时候不使用?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (33)

内联是对编译器的提示或请求,它用于避免函数调用开销,我们可以根据什么基础来确定某个函数是否是内联的候选函数?在这种情况下,应该避免内联?

提问于
用户回答回答于

做:

  • 使用inline代替#define
  • 很小功能是很好的候选人inline更快的代码和更小的可执行文件(更多的机会留在代码缓存中)
  • 功能小经常打电话

不要:

  • 大功能:导致更大的可执行文件,这会严重影响性能,而不管调用开销的执行速度如何。
  • I/O绑定的内联函数
  • 这种功能很少使用。
  • 构造函数和析构函数:即使是空的,编译器也会为它们生成代码。
  • 在开发库时破坏二进制兼容性:
    • 内联现有功能
    • 更改内联函数或使内联函数非内联:库的早期版本调用旧的实现。

在开发库时,为了使类将来可扩展,应该:

  • 添加非内联虚拟析构函数,即使主体为空。
  • 使所有构造函数非内联
  • 写入复制构造函数和赋值操作符的非内联实现,除非类不能通过值进行复制。

可以将函数定义为inline...。例如:

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

inline说明符是对编译器的提示,它应该尝试为fac()内联而不是为函数一次设定代码,然后通过通常的函数调用机制进行调用。聪明的编译器可以生成常量。720打电话fac(6).由于相互递归的内联函数、递归或不依赖于输入的内联函数的可能性,使得无法保证inline函数实际上是内联的。编译器的聪明程度无法立法,所以一个编译器可能会生成720,另一种6 * fac(5),还有另一个没有内联的电话。 为了使内联在没有异常巧妙的编译和链接功能的情况下成为可能,内联函数的定义--而不仅仅是声明--必须在范围内(§9.2)。安inline特殊词不影响函数的语义。尤其是,内联函数仍然具有唯一的地址,因此static内联函数的变量(§7.1.2)。

用户回答回答于

inline和优化没什么关系。inline如果给定定义的函数在程序中多次发生,则对编译器的指令是不产生错误的,并且保证定义将在所使用的每个转换中发生,并且在任何地方都会出现该定义,定义的定义将完全相同。

鉴于上述规则,inline适用于身体不需要的短函数,包括对声明所需内容的额外依赖。每次遇到定义时,都必须对其进行解析,并生成其主体的代码,因此,它意味着在单个源文件中只定义一次的函数上需要一些编译器开销。

编译器可能内联(即用执行该函数的操作的代码替换对函数的调用)它选择的任何函数调用。过去的情况是,它“显然”不能内联一个函数,而这个函数在调用的同一个翻译单元中没有声明,但是随着链接时间优化的使用越来越多,即使现在也不是这样。同样正确的事实是,函数被标记为inline可能没有内线。

扫码关注云+社区