内联函数与预处理器宏

新手上路,请多包涵

内联函数与预处理器宏有何不同?

原文由 Subodh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 507
2 个回答

预处理器宏只是应用于您的代码的替换模式。它们几乎可以在您的代码中的任何地方使用,因为它们在任何编译开始之前被它们的扩展替换。

内联函数是其主体直接注入其调用站点的实际函数。它们只能在函数调用合适的地方使用。

现在,就在类似函数的上下文中使用宏与内联函数而言,请注意:

  • 宏不是类型安全的,无论它们在语法上是否正确都可以扩展 - 编译阶段将报告由宏扩展问题导致的错误。
  • 宏可以在您不期望的上下文中使用,从而导致问题
  • 宏更灵活,因为它们可以扩展其他宏 - 而内联函数不一定这样做。
  • 宏可能会因为它们的扩展而产生副作用,因为输入表达式会被复制到它们出现在模式中的任何位置。
  • 内联函数并不总是保证被内联 - 一些编译器只在发布版本中这样做,或者当它们被专门配置为这样做时。此外,在某些情况下可能无法进行内联。
  • 内联函数可以为变量(尤其是静态变量)提供范围,预处理器宏只能在代码块 {…} 中执行此操作,而静态变量的行为方式不会完全相同。

原文由 LBushkin 发布,翻译遵循 CC BY-SA 2.5 许可协议

要了解 宏和内联函数 之间的区别,首先我们应该知道它们到底是什么以及何时应该使用它们。

功能

 int Square(int x)
{
    return(x*x);
}

int main()
{
    int value = 5;
    int result = Square(value);
    cout << result << endl;
}

  • 函数调用有与之相关的开销。函数执行完毕后,它需要知道返回到哪里,所以在调用函数之前将返回地址存储在堆栈中。对于小型应用程序,这可能不是问题,但在金融应用程序中,每秒发生数千笔交易,函数调用可能过于昂贵。

宏:

 # define Square(x) x*x;
int main()
{
    int value = 5;
    int result = Square(value);
    cout << result << endl;
}

  • 在预处理阶段应用宏。在此阶段,用 #define 关键字编写的语句将被替换或扩展

整数结果 = 平方(x*x)

但是宏可能会导致意外行为。

 #define Square(x) x*x
int main()
{
    int val = 5;
    int result = Square(val + 1);
    cout << result << endl;
}

这里的输出是 11 ,而不是 36。

内联函数

 inline int Square(int x)
{
    return x * x;
}

int main()
{
    int val = 5;
    int result = Square(val + 1);
    cout << result << endl;
}

输出: 36

inline 关键字要求编译器将函数调用替换为函数体。这里的输出是正确的,因为它首先计算表达式,然后使用结果来执行函数的主体。内联函数减少了函数调用开销,因为不需要将返回地址或函数参数存储到堆栈中。

宏和内联函数的比较:

  1. 宏通过文本替换工作,而内联函数复制函数的逻辑。
  2. 由于替换,宏很容易出错,而内联函数可以安全使用。
  3. 宏不能分配给函数指针;内联函数可以。
  4. 宏很难与多行代码一起使用,而内联函数则不然。
  5. 在 C++ 中,宏不能与成员函数一起使用,而内联函数可以。

结论:

内联函数有时比宏更有用,因为它们使用安全,但也可以减少函数调用开销。 inline 关键字是对编译器的 _请求_,某些函数不会被内联,例如:

  • 大型函数
  • 具有太多条件参数的函数
  • 递归代码和带有循环的代码等。

这是一件好事,因为它允许编译器确定以另一种方式做事是否更好。

原文由 Sheetal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题