什么时候使用内联函数,什么时候不使用它? [复制]

2024-04-12

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

那么,根据什么可以确定一个函数是否适合内联呢? 在什么情况下应该避免内联?


避免函数调用的成本只是故事的一半。

do:

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

don't:

  • 大函数:会导致更大的可执行文件,这会严重影响性能,尽管调用开销会导致执行速度更快
  • 受 I/O 限制的内联函数
  • 该功能很少使用
  • 构造函数和析构函数:即使为空,编译器也会为它们生成代码
  • breaking binary compatibility when developing libraries:
    • 内联现有函数
    • 更改内联函数或使内联函数成为非内联:以前版本的库调用旧实现

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

  • 添加非内联虚拟析构函数,即使主体为空
  • 使所有构造函数成为非内联
  • 编写复制构造函数和赋值运算符的非内联实现,除非类不能按值复制

请记住,inline关键字是对编译器的提示:编译器可能决定不内联函数,也可以决定内联未标记的函数inline首先。我通常避免标记功能inline(除了编写非常非常小的函数时)。

关于性能,明智的方法是(一如既往)分析应用程序,然后最终inline代表瓶颈的一组函数。

参考:

  • 内联或不内联 http://www.ddj.com/architect/184405660
  • [9] 内联函数 http://www.parashift.com/c++-faq-lite/inline-functions.html
  • C++ 的策略/二进制兼容性问题 http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
  • GotW #33:内联 http://www.gotw.ca/gotw/033.htm
  • 内联还原 http://www.ddj.com/cpp/184403879
  • 有效的 C++ - 第 33 条:明智地使用内联

编辑:Bjarne Stroustrup,《C++ 编程语言》:

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

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

The inline说明符是对编译器的一个提示,它应该尝试为调用生成代码fac()内联而不是一次性编写函数代码,然后通过通常的函数调用机制进行调用。聪明的编译器可以生成常量720打电话fac(6)。相互递归内联函数、根据输入是否递归的内联函数等的可能性,使得不可能保证每次调用inline函数实际上是内联的。编译器的聪明程度无法立法,因此一个编译器可能会生成720, 其他6 * fac(5),还有一个未内联的调用fac(6).

为了在缺乏异常聪明的编译和链接设施的情况下使内联成为可能,内联函数的定义(而不仅仅是声明)必须在范围内(第 9.2 节)。一个inlineespecifier 不影响函数的语义。特别是,内联函数仍然具有唯一的地址,因此static内联函数的变量(第 7.1.2 节)。

EDIT2:ISO-IEC 14882-1998,7.1.2 函数说明符

带有一个函数声明(8.3.5、9.3、11.4)inline说明符声明一个内联函数。内联说明符向实现表明,在调用时函数体的内联替换优先于通常的函数调用机制。不需要实现在调用时执行此内联替换;然而,即使省略此内联替换,仍应遵守 7.1.2 定义的内联函数的其他规则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么时候使用内联函数,什么时候不使用它? [复制] 的相关文章

  • type_info 的 std::is_convertible

    在 C 11 中 可以通过以下方式确定类型 A 的变量是否可以隐式转换为类型 B using std is convertible
  • 使用 c# 的 StrucLayout 和 FieldOffset 表示联合位域

    据我了解 为了在 C 中表示联合 我需要使用 StructLayout LayoutKind Explicit 和 FieldOffset x 属性来指定联合内的字节偏移量 但是 我有一个想要表示的以下联合 并且 FieldOffset a
  • 主从视图中聚合详细信息值

    我在一些自定义实体中有主从关系 假设我有以下结构 class Master INotifyPropertyChanged public int Id get set property changed implementation publi
  • DataGridView 中的 C# FormatException

    我创建了一个带有一些列的 DataGridView 订单列仅允许用户输入 int 数字 当我输入 j 例如 时 它会抛出 FormatException 并且我尝试添加 try catch 来解决问题 但它看起来不起作用 private v
  • 如何包含字符串标头?

    我正在尝试了解strings 但不同的来源告诉我要包含不同的标头 有人说用
  • 服务层和存储库

    我使用 MVC 框架已经有一段时间了 我真的很喜欢如何分离关注点 我养成了让控制器做大量工作的坏习惯 所以我真的在寻求一些建议 当我第一次开始使用 MVC 时 我经常在数据库工作完成后让控制器对模型进行操作 我知道这很糟糕 所以将这项工作转
  • 双击,怎么处理?

    我试图找出如何处理用鼠标左键 或任何 双击 但我找不到任何有关它的信息 有谁能够帮助我 我不想编写自己的双击处理程序 GLFW REPEAT 不适用于鼠标按钮 编写自己的双击处理程序有什么问题吗 只需节省鼠标单击发生的时间 例如和std c
  • 如何将用户输入与枚举值映射?

    我有一个基本的enum宣言 enum Title Prof Dr Mr Mdm Mrs Miss NA 我正在尝试将用户输入 0 1 2 3 4 5 AnyNumber 映射为正确的值enum像这样 std map
  • 检查二维数组中是否存在任何数字的程序

    我知道如何检查数组中是否存在数字 但不知道如何检查数字是否存在于数组中2D array 请帮我2D include
  • 如何使取消按钮像“X”按钮一样工作?

    在我的 XAML 文件中 我有一个窗口 我试图将其设置为无论用户单击 X 按钮还是单击 取消 按钮 行为都是相同的 我的缩写代码如下 public partial class Dialog Window private void Windo
  • 有没有办法从继承的属性中删除属性?

    是否可以从继承的属性中删除属性 我认为通过使用new关键字我可以这样做 public class Person Required public string FirstName get set Required public string
  • Scrollable Control中的Scroll/Scroll有什么用?

    ScrollableControl 类有 2 个受保护的布尔属性 HScroll 和 VScroll As the document https msdn microsoft com en us library system windows
  • string.Empty 与 null。您使用哪一个?

    最近工作的同事告诉我不要使用string Empty设置字符串变量时但使用null因为它污染了堆栈 他说不做 string myString string Empty but do string mystring null 真的有关系吗 我
  • C# 抽象泛型方法

    C net 3 5 我正在尝试创建一个具有通用方法的基类 从它继承的类应该指定方法的类型 这样做的前提是创建管理过滤的类 所以我有 public abstract class FilterBase NEED Help Declaring t
  • Excel VSTO 工作簿新活动

    在 Excel 2007 的一个 Excel 插件项目中 我需要检查创建新工作簿的事件 我还需要捕捉 Workbook Open 事件 我很容易做到这一点 在我在互联网上的研究中 我发现了以下内容 打开任何工作簿时都会引发 Applicat
  • 将 .NET 枚举转换为 GraphQL EnumerationGraphType

    如何将枚举转换为 GraphQL 使用的 EnumerationGraphType 这是一个例子来说明我在说什么 public enum MeetingStatusType Tentative Unconfirmed Confirmed p
  • 为使用 SSH.NET SshClient.CreateShellStream 执行的命令 (sudo/su) 提供子命令

    我正在尝试使用 Renci SSH NET 从 C Web 应用程序连接到远程 Linux 服务器并执行 shell 脚本 我想一个接一个地运行脚本 但不知道如何运行脚本并读取输出并将其存储在标签中 我已经尝试了下面的代码 但无法一行接一行
  • 注销租约抛出 InvalidOperationException

    我有一个使用插件的应用程序 我在另一个应用程序域中加载插件 我使用 RemoteHandle 类http www pocketsilicon com post Things That Make My Life Hell Part 1 App
  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient

随机推荐